1 #ifndef _INTERPRETER_CPP_ 2 #define _INTERPRETER_CPP_ 4 #ifndef _MADARA_NO_KARL_ 262 virtual ~
Eval (
void);
344 virtual ~
Print (
void);
428 virtual ~
Power (
void);
570 virtual ~
Size (
void);
791 virtual ~
Sleep (
void);
811 virtual ~
Type (
void);
831 virtual ~
Isinf (
void);
1178 Symbol * rhs,
int compare_type,
1220 virtual ~
List (
void);
1268 virtual ~
Add (
void);
1289 virtual ~
And (
void);
1333 virtual ~
Both (
void);
1787 virtual ~
Not (
void);
1885 :
Symbol (logger, left, right, precedence)
1897 :
Operator (logger, left, right, precedence)
1910 :
madara::expression::
Symbol (logger, 0, right, precedence)
1962 "Number::build: KARL COMPILE ERROR: " 1965 message +=
" has a left or right child. Likely missing a semi-colon\n";
2005 "Negate::build: KARL COMPILE ERROR: " 2006 "Negate(-) has a left child. Likely missing a semi-colon\n");
2009 "Negate(-) has a left child. Likely missing a semi-colon\n");
2085 "array[]::build: KARL COMPILE ERROR: " 2086 "array[] has a left or right child. Likely missing a semi-colon\n");
2089 "array[]::build: KARL COMPILE ERROR: " 2090 "array[] has a left or right child. Likely missing a semi-colon\n");
2140 "#clear_var::build: KARL COMPILE ERROR: " 2141 "#clear_var has a left or right child. Likely missing a semi-colon\n");
2144 "#clear_var::build: KARL COMPILE ERROR: " 2145 "#clear_var has a left or right child. Likely missing a semi-colon\n");
2178 "#delete_var::build: KARL COMPILE ERROR: " 2179 "#delete_var has a left or right child. Likely missing a semi-colon\n");
2182 "#delete_var::build: KARL COMPILE ERROR: " 2183 "#delete_var has a left or right child. Likely missing a semi-colon\n");
2217 "#evaluate::build: KARL COMPILE ERROR: " 2218 "#evaluate has a left or right child. Likely missing a semi-colon\n");
2221 "#evaluate::build: KARL COMPILE ERROR: " 2222 "#evaluate has a left or right child. Likely missing a semi-colon\n");
2256 "#expand_env::build: KARL COMPILE ERROR: " 2257 "#expand_env has a left or right child. Likely missing a semi-colon\n");
2260 "#expand_env::build: KARL COMPILE ERROR: " 2261 "#expand_env has a left or right child. Likely missing a semi-colon\n");
2295 "#expand::build: KARL COMPILE ERROR: " 2296 "#expand has a left or right child. Likely missing a semi-colon\n");
2299 "#expand::build: KARL COMPILE ERROR: " 2300 "#expand has a left or right child. Likely missing a semi-colon\n");
2335 "#fragment::build: KARL COMPILE ERROR: " 2336 "#fragment has a left or right child. Likely missing a semi-colon\n");
2339 "#fragment::build: KARL COMPILE ERROR: " 2340 "#fragment has a left or right child. Likely missing a semi-colon\n");
2374 "#log_level::build: KARL COMPILE ERROR: " 2375 "#log_level has a left or right child. Likely missing a semi-colon\n");
2378 "#log_level::build: KARL COMPILE ERROR: " 2379 "#log_level has a left or right child. Likely missing a semi-colon\n");
2414 "#get_clock::build: KARL COMPILE ERROR: " 2415 "#get_clock has a left or right child. Likely missing a semi-colon\n");
2418 "#get_clock::build: KARL COMPILE ERROR: " 2419 "#get_clock has a left or right child. Likely missing a semi-colon\n");
2452 "#get_time::build: KARL COMPILE ERROR: " 2453 "#get_time has a left or right child. Likely missing a semi-colon\n");
2456 "#get_time::build: KARL COMPILE ERROR: " 2457 "#get_time has a left or right child. Likely missing a semi-colon\n");
2490 "#get_time_s::build: KARL COMPILE ERROR: " 2491 "#get_time_s has a left or right child. Likely missing a semi-colon\n");
2494 "#get_time_s::build: KARL COMPILE ERROR: " 2495 "#get_time_s has a left or right child. Likely missing a semi-colon\n");
2528 "#set_clock::build: KARL COMPILE ERROR: " 2529 "#set_clock has a left or right child. Likely missing a semi-colon\n");
2532 "#set_clock::build: KARL COMPILE ERROR: " 2533 "#set_clock has a left or right child. Likely missing a semi-colon\n");
2565 "#set_fixed::build: KARL COMPILE ERROR: " 2566 "#set_fixed has a left or right child. Likely missing a semi-colon\n");
2569 "#set_fixed::build: KARL COMPILE ERROR: " 2570 "#set_fixed has a left or right child. Likely missing a semi-colon\n");
2603 "#set_precision::build: KARL COMPILE ERROR: " 2604 "#set_precision has a left or right child. Likely missing a semi-colon\n");
2607 "#set_precision::build: KARL COMPILE ERROR: " 2608 "#set_precision has a left or right child. Likely missing a semi-colon\n");
2641 "#scientific::build: KARL COMPILE ERROR: " 2642 "#scientific has a left or right child. Likely missing a semi-colon\n");
2645 "#scientific::build: KARL COMPILE ERROR: " 2646 "#scientific has a left or right child. Likely missing a semi-colon\n");
2680 "#print::build: KARL COMPILE ERROR: " 2681 "#print has a left or right child. Likely missing a semi-colon\n");
2684 "#print::build: KARL COMPILE ERROR: " 2685 "#print has a left or right child. Likely missing a semi-colon\n");
2717 "#cos::build: KARL COMPILE ERROR: " 2718 "#cos has a left or right child. Likely missing a semi-colon\n");
2721 "#cos::build: KARL COMPILE ERROR: " 2722 "#cos has a left or right child. Likely missing a semi-colon\n");
2755 "#sin::build: KARL COMPILE ERROR: " 2756 "#sin has a left or right child. Likely missing a semi-colon\n");
2759 "#sin::build: KARL COMPILE ERROR: " 2760 "#sin has a left or right child. Likely missing a semi-colon\n");
2792 "#tan::build: KARL COMPILE ERROR: " 2793 "#tan has a left or right child. Likely missing a semi-colon\n");
2796 "#tan::build: KARL COMPILE ERROR: " 2797 "#tan has a left or right child. Likely missing a semi-colon\n");
2829 "#pow::build: KARL COMPILE ERROR: " 2830 "#pow has a left or right child. Likely missing a semi-colon\n");
2833 "#pow::build: KARL COMPILE ERROR: " 2834 "#pow has a left or right child. Likely missing a semi-colon\n");
2866 "#sqrt::build: KARL COMPILE ERROR: " 2867 "#sqrt has a left or right child. Likely missing a semi-colon\n");
2870 "#sqrt::build: KARL COMPILE ERROR: " 2871 "#sqrt has a left or right child. Likely missing a semi-colon\n");
2905 "#print_system_calls::build: KARL COMPILE ERROR: " 2906 "#print_system_calls has a left or right child. Likely missing a semi-colon\n");
2909 "#print_system_calls::build: KARL COMPILE ERROR: " 2910 "#print_system_calls has a left or right child. Likely missing a semi-colon\n");
2943 "#rand_double::build: KARL COMPILE ERROR: " 2944 "#rand_double has a left or right child. Likely missing a semi-colon\n");
2947 "#rand_double::build: KARL COMPILE ERROR: " 2948 "#rand_double has a left or right child. Likely missing a semi-colon\n");
2981 "#rand_int::build: KARL COMPILE ERROR: " 2982 "#rand_int has a left or right child. Likely missing a semi-colon\n");
2985 "#rand_int::build: KARL COMPILE ERROR: " 2986 "#rand_int has a left or right child. Likely missing a semi-colon\n");
3019 "#read_file::build: KARL COMPILE ERROR: " 3020 "#read_file has a left or right child. Likely missing a semi-colon\n");
3023 "#read_file::build: KARL COMPILE ERROR: " 3024 "#read_file has a left or right child. Likely missing a semi-colon\n");
3057 "#write_file::build: KARL COMPILE ERROR: " 3058 "#write_file has a left or right child. Likely missing a semi-colon\n");
3061 "#write_file::build: KARL COMPILE ERROR: " 3062 "#write_file has a left or right child. Likely missing a semi-colon\n");
3096 "#size::build: KARL COMPILE ERROR: " 3097 "#size has a left or right child. Likely missing a semi-colon\n");
3100 "#size::build: KARL COMPILE ERROR: " 3101 "#size has a left or right child. Likely missing a semi-colon\n");
3134 "#sleep::build: KARL COMPILE ERROR: " 3135 "#sleep has a left or right child. Likely missing a semi-colon\n");
3138 "#sleep::build: KARL COMPILE ERROR: " 3139 "#sleep has a left or right child. Likely missing a semi-colon\n");
3172 "#to_buffer::build: KARL COMPILE ERROR: " 3173 "#to_buffer has a left or right child. Likely missing a semi-colon\n");
3176 "#to_buffer::build: KARL COMPILE ERROR: " 3177 "#to_buffer has a left or right child. Likely missing a semi-colon\n");
3210 "#to_double::build: KARL COMPILE ERROR: " 3211 "#to_double has a left or right child. Likely missing a semi-colon\n");
3214 "#to_double::build: KARL COMPILE ERROR: " 3215 "#to_double has a left or right child. Likely missing a semi-colon\n");
3248 "#to_doubles::build: KARL COMPILE ERROR: " 3249 "#to_doubles has a left or right child. Likely missing a semi-colon\n");
3252 "#to_doubles::build: KARL COMPILE ERROR: " 3253 "#to_doubles has a left or right child. Likely missing a semi-colon\n");
3286 "#to_host_dirs::build: KARL COMPILE ERROR: " 3287 "#to_host_dirs has a left or right child. Likely missing a semi-colon\n");
3290 "#to_host_dirs::build: KARL COMPILE ERROR: " 3291 "#to_host_dirs has a left or right child. Likely missing a semi-colon\n");
3324 "#to_integer::build: KARL COMPILE ERROR: " 3325 "#to_integer has a left or right child. Likely missing a semi-colon\n");
3328 "#to_integer::build: KARL COMPILE ERROR: " 3329 "#to_integer has a left or right child. Likely missing a semi-colon\n");
3362 "#to_integers::build: KARL COMPILE ERROR: " 3363 "#to_integers has a left or right child. Likely missing a semi-colon\n");
3366 "#to_integers::build: KARL COMPILE ERROR: " 3367 "#to_integers has a left or right child. Likely missing a semi-colon\n");
3400 "#to_string::build: KARL COMPILE ERROR: " 3401 "#to_string has a left or right child. Likely missing a semi-colon\n");
3404 "#to_string::build: KARL COMPILE ERROR: " 3405 "#to_string has a left or right child. Likely missing a semi-colon\n");
3438 "#type::build: KARL COMPILE ERROR: " 3439 "#type has a left or right child. Likely missing a semi-colon\n");
3442 "#type::build: KARL COMPILE ERROR: " 3443 "#type has a left or right child. Likely missing a semi-colon\n");
3476 "#is_inf::build: KARL COMPILE ERROR: " 3477 "#is_inf has a left or right child. Likely missing a semi-colon\n");
3480 "#is_inf::build: KARL COMPILE ERROR: " 3481 "#is_inf has a left or right child. Likely missing a semi-colon\n");
3495 precondition_ (precondition), condition_ (condition),
3496 postcondition_ (postcondition), body_ (body),
context_ (context)
3567 "var--::build: KARL COMPILE ERROR: " 3568 "var-- has a left child. Likely missing a semi-colon\n");
3571 "#var--::build: KARL COMPILE ERROR: " 3572 "#var-- has a left child. Likely missing a semi-colon\n");
3609 "var++::build: KARL COMPILE ERROR: " 3610 "var++ has a left child. Likely missing a semi-colon\n");
3613 "#var++::build: KARL COMPILE ERROR: " 3614 "#var++ has a left child. Likely missing a semi-colon\n");
3651 "--var::build: KARL COMPILE ERROR: " 3652 "--var has a left child. Likely missing a semi-colon\n");
3655 "--var::build: KARL COMPILE ERROR: " 3656 "--var has a left child. Likely missing a semi-colon\n");
3692 "++var::build: KARL COMPILE ERROR: " 3693 "++var has a left child. Likely missing a semi-colon\n");
3696 "++var::build: KARL COMPILE ERROR: " 3697 "++var has a left child. Likely missing a semi-colon\n");
3736 "Not(!)::build: KARL COMPILE ERROR: " 3737 "Logical Not(!) has a left child. Likely missing a semi-colon\n");
3740 "Not(!)::build: KARL COMPILE ERROR: " 3741 "Logical Not(!) has a left child. Likely missing a semi-colon\n");
3747 ++i, right = next->
right_, next = dynamic_cast <
Not *> (next->
right_)) {}
3788 "sqrt::build: KARL COMPILE ERROR: " 3789 "sqrt has a left child. Likely missing a semi-colon\n");
3792 "sqrt::build: KARL COMPILE ERROR: " 3793 "sqrt has a left child. Likely missing a semi-colon\n");
3806 key_ (key), context_ (context)
3829 "Variable::build: KARL COMPILE ERROR: " 3832 message +=
") has a left or right child. Likely missing a semi-colon\n";
3845 else if (
key_ ==
"false")
3849 else if (
key_ ==
"nan")
3853 else if (
key_ ==
"inf")
3892 "ArrayRef::build: KARL COMPILE ERROR: ";
3894 message +=
"[] has a left or right child. Likely missing a semi-colon\n";
4042 compare_type_ (compare_type),
context_ (context)
4132 for (; next; next = dynamic_cast <
Add *> (left))
4152 nodes_.push_front (left->build ());
4209 for (; next; next = dynamic_cast <
And *> (left))
4229 nodes_.push_front (left->build ());
4279 Or * next = dynamic_cast <
Or *> (
left_);
4287 for (; next; next = dynamic_cast <
Or *> (left))
4307 nodes_.push_front (left->build ());
4367 for (; next; next = dynamic_cast <
Both *> (left))
4387 nodes_.push_front (left->build ());
4396 for (; next; next = dynamic_cast <
Both *> (right))
4416 nodes_.push_back (right->build ());
4475 for (; next; next = dynamic_cast <
ReturnRight *> (left))
4495 nodes_.push_front (left->build ());
4504 for (; next; next = dynamic_cast <
ReturnRight *> (right))
4524 nodes_.push_back (right->build ());
4582 for (; next; next = dynamic_cast <
Sequence *> (left))
4602 nodes_.push_front (left->build ());
4611 for (; next; next = dynamic_cast <
Sequence *> (right))
4631 nodes_.push_back (right->build ());
4819 *(this->
logger_), left, right);
5084 std::string::size_type &i,
5085 int & accumulated_precedence,
5086 ::std::list<Symbol *>& list,
5087 Symbol *& returnableInput)
5089 ::std::list <Symbol *> substr_list;
5090 Symbol * lastValidInput (0);
5091 std::string::size_type begin = i;
5093 Symbol * body (0), *user_pre (0), *user_cond (0), *user_post (0);
5096 std::string::size_type count (0);
5101 variable =
".MADARA_I";
5104 bool delimiter_found =
false, handled =
false, equal_to =
false;
5105 std::string::size_type delimiter_begin = 0;
5106 std::string::size_type delimiter_end = 0;
5107 int paren_depth = 0;
5108 int index_depth = 0;
5111 for (; i < input.length (); ++i)
5113 if (index_depth == 0 && paren_depth == 0 &&
5114 input[i] ==
'-' && !delimiter_found)
5116 delimiter_found =
true;
5117 delimiter_begin = i;
5119 else if (index_depth == 0 && paren_depth == 0 &&
5120 delimiter_found && input[i] ==
'>')
5124 else if (input[i] ==
']')
5126 if (index_depth == 0 && paren_depth == 0)
5135 else if (input[i] ==
'(')
5139 else if (input[i] ==
'[')
5143 else if (input[i] ==
')')
5145 if (paren_depth == 0)
5160 if (delimiter_found && delimiter_end == 0)
5162 delimiter_found =
false;
5166 if (!delimiter_found)
5170 substr = input.substr (begin, i - begin);
5172 Symbol * index =
nullptr;
5175 count < substr.length ();)
5177 main_loop (context, substr, count, lastValidInput,
5178 handled, accumulated_precedence, substr_list);
5182 "madara::expression::Interpreter: " 5183 "KaRL: For loop: Array reference created at %s\n",
5187 if (!substr_list.empty ())
5189 index = substr_list.back ();
5190 substr_list.clear ();
5197 if (i + 2 < input.size ())
5199 if (input[i + 1] ==
'+' && input[i + 2] ==
'+')
5207 else if (input[i + 1] ==
'-' && input[i + 2] ==
'-')
5217 lastValidInput = op;
5219 precedence_insert (context, op, list);
5221 returnableInput = op;
5227 "madara::expression::Interpreter: " 5228 "KaRL: For loop: Within input string, the for loop delimiter begins at %d" 5229 " and ends at %d (should be at least 1). Loop construct begins at " 5230 "%d and ends at %d\n",
5231 (int)delimiter_begin, (
int)delimiter_end, (int)begin, (
int)i);
5235 if (input[i] ==
']')
5237 else if (input[i] !=
')')
5242 "madara::expression::Interpreter: " 5243 "KARL COMPILE ERROR:: No closing delimiter (']' or ')')" 5244 " has been specified on the for loop.\n");
5247 "KARL COMPILE ERROR:: No closing delimiter (']' or ')')" 5248 " has been specified on the for loop.\n");
5257 if (delimiter_found)
5260 if (delimiter_begin - begin > 0)
5263 substr = input.substr (begin, delimiter_begin - begin);
5266 count < substr.length ();)
5268 main_loop (context, substr, count, lastValidInput,
5269 handled, accumulated_precedence, substr_list);
5273 "madara::expression::Interpreter: " 5274 "KaRL: For loop: Precondition is set to %s\n", substr.c_str ());
5277 if (!substr_list.empty ())
5279 user_pre = substr_list.back ();
5280 substr_list.clear ();
5286 "madara::expression::Interpreter: " 5287 "KaRL: For loop: No loop precondition was specified\n");
5291 if (delimiter_end - delimiter_begin > 1)
5295 substr = input.substr (delimiter_begin + 1, delimiter_end - (delimiter_begin + 1));
5298 count < substr.length ();)
5300 main_loop (context, substr, count, lastValidInput,
5301 handled, accumulated_precedence, substr_list);
5305 "madara::expression::Interpreter: " 5306 "KaRL: For loop: Postcondition is set to %s\n", substr.c_str ());
5309 if (!substr_list.empty ())
5311 user_post = substr_list.back ();
5313 substr_list.clear ();
5319 "KaRL: For loop: No loop special increment was specified\n");
5323 if (i - delimiter_end >= 2)
5326 substr = input.substr (delimiter_end + 1, i - (delimiter_end + 1));
5329 count < substr.length ();)
5331 main_loop (context, substr, count, lastValidInput,
5332 handled, accumulated_precedence, substr_list);
5336 if (!substr_list.empty ())
5339 "KaRL: For loop: Condition is set to %s\n", substr.c_str ());
5341 user_cond = substr_list.back ();
5342 substr_list.clear ();
5347 "KaRL: For loop: Condition was not set to %s\n", substr.c_str ());
5353 "KaRL: For loop: No loop condition was specified\n");
5360 substr = input.substr (begin, i - begin);
5363 count < substr.length ();)
5365 main_loop (context, substr, count, lastValidInput,
5366 handled, accumulated_precedence, substr_list);
5370 "KaRL: For loop: Condition only is set to %s\n", substr.c_str ());
5373 if (!substr_list.empty ())
5375 user_cond = substr_list.back ();
5376 substr_list.clear ();
5400 "KaRL: For loop: Postcondition is set to 1 (def)\n");
5404 for (++i; i < input.length () && is_whitespace (input[i]); ++i);
5407 if (i < input.length () && input[i] ==
'(')
5413 "KaRL: For loop: Body is reading from %s\n",
5414 input.substr (i, input.size () - i).c_str ());
5418 handle_parenthesis (context, input, i, lastValidInput, handled,
5419 accumulated_precedence, substr_list);
5421 if (!substr_list.empty ())
5423 body = substr_list.back ();
5424 substr_list.clear ();
5437 if (variable_node && number)
5440 "KaRL: For loop: Body is a simple assignment of variable %s to %s\n",
5441 variable_node->
key_.c_str (), number->item_.to_string ().c_str ());
5446 "KaRL: For loop: For loop has a complex body\n");
5450 precondition->
right_ = user_pre;
5458 post_val = number->
item_;
5464 number = dynamic_cast <
Number *> (user_cond);
5467 cond_val = number->
item_;
5472 int compare_type (0);
5480 var_node, post_val, user_post, context);
5485 user_cond, compare_type, context);
5489 precondition, condition, postcondition, body, context);
5492 precedence_insert (context, op, list);
5522 delete precondition->
right_;
5523 precondition->
right_ = user_cond;
5526 precedence_insert (context, precondition, list);
5537 std::string::size_type &i,
5538 int & accumulated_precedence,
5539 ::std::list<Symbol *>& list,
5540 Symbol *& lastValidInput)
5543 std::string::size_type j = 1;
5545 for (; i + j < input.length () && is_alphanumeric (input[i + j]); ++j)
5556 for (; i < input.length () && is_whitespace (input[i]); ++i);
5559 if (is_reserved_word (name))
5564 "madara::expression::Interpreter: " 5565 "Inserting true(1) into expression tree.\n");
5568 number->add_precedence (accumulated_precedence);
5569 lastValidInput = number;
5571 precedence_insert (context, number, list);
5573 else if (name ==
"false")
5576 "madara::expression::Interpreter: " 5577 "Inserting false(0) into expression tree.\n");
5580 number->add_precedence (accumulated_precedence);
5581 lastValidInput = number;
5583 precedence_insert (context, number, list);
5585 else if (name ==
"nan")
5588 "madara::expression::Interpreter: " 5589 "Inserting NAN into expression tree.\n");
5593 lastValidInput = number;
5595 precedence_insert (context, number, list);
5597 else if (name ==
"inf")
5600 "madara::expression::Interpreter: " 5601 "Inserting INFINITY into expression tree.\n");
5605 lastValidInput = number;
5607 precedence_insert (context, number, list);
5611 else if (i < input.length () && input[i] ==
'(')
5615 function->add_precedence (accumulated_precedence);
5617 bool handled =
false;
5619 ::std::list<Symbol *> param_list;
5621 int local_precedence = 0;
5622 Symbol * local_last_valid = 0;
5627 handle_parenthesis (context, input, i, local_last_valid, handled,
5628 local_precedence, param_list,
true);
5633 function->nodes_.resize (param_list.size ());
5636 for (::std::list<Symbol *>::iterator arg = param_list.begin ();
5637 arg != param_list.end (); ++arg, ++cur)
5639 function->nodes_[cur] = (*arg)->build ();
5644 precedence_insert (context,
function, list);
5647 else if (i < input.length () && input[i] ==
'[')
5650 handle_for_loop (context, name, input, i, accumulated_precedence,
5651 list, lastValidInput);
5659 if (i + 1 < input.size ())
5661 if (input[i] ==
'+' && input[i + 1] ==
'+')
5669 else if (input[i] ==
'-' && input[i + 1] ==
'-')
5679 lastValidInput = op;
5681 precedence_insert (context, op, list);
5691 std::string::size_type &i,
int & accumulated_precedence,
5692 ::std::list<madara::expression::Symbol *>& list,
5695 std::string::size_type j = 0;
5698 for (; i + j < input.length (); ++j)
5700 if (input[i + j] == opener && input[i + j - 1] !=
'\\')
5708 lastValidInput = number;
5714 precedence_insert (context, number, list);
5722 std::string::size_type &i,
5723 int & accumulated_precedence,
5724 ::std::list<Symbol *>& list,
5725 Symbol *& lastValidInput)
5728 std::string::size_type j = 1;
5730 for (; i + j < input.length () && is_alphanumeric (input[i + j]); ++j)
5741 for (; i < input.length () && is_whitespace (input[i]); ++i);
5743 if (i < input.length () && input[i] ==
'(')
5747 char first_char = 0;
5749 if (name.size () > 1)
5751 first_char = name[1];
5757 if (name ==
"#buffer")
5763 if (name ==
"#clear_var" || name ==
"#clear_variable")
5767 else if (name ==
"#cos")
5769 call =
new Cos (context);
5773 if (name ==
"#delete_var" || name ==
"#delete_variable")
5777 else if (name ==
"#double")
5781 else if (name ==
"#doubles")
5787 if (name ==
"#eval" || name ==
"#evaluate")
5789 call =
new Eval (context);
5791 else if (name ==
"#expand" || name ==
"#expand_statement")
5795 else if (name ==
"#expand_env" || name ==
"#expand_envs")
5801 if (name ==
"#fragment")
5805 else if (name ==
"#fixed")
5811 if (name ==
"#get_clock")
5815 else if (name ==
"#get_time" || name ==
"#get_time_ns" || name ==
"#get_time_nano")
5819 else if (name ==
"#get_time_seconds" || name ==
"#get_time_s")
5825 if (name ==
"#integer")
5829 else if (name ==
"#integers")
5833 else if (name ==
"#isinf")
5835 call =
new Isinf (context);
5839 if (name ==
"#log_level")
5847 call =
new Power (context);
5849 else if (name ==
"#print")
5851 call =
new Print (context);
5853 else if (name ==
"#print_system_calls" || name ==
"#print_system_call")
5857 else if (name ==
"#precision")
5863 if (name ==
"#rand_double")
5867 else if (name ==
"#rand_int" || name ==
"#rand_integer")
5871 else if (name ==
"#read_file")
5877 if (name ==
"#scientific")
5881 else if (name ==
"#set_clock")
5885 else if (name ==
"#set_fixed")
5889 else if (name ==
"#set_precision")
5893 else if (name ==
"#set_scientific")
5897 else if (name ==
"#sin")
5899 call =
new Sin (context);
5901 else if (name ==
"#size")
5903 call =
new Size (context);
5905 else if (name ==
"#sleep")
5907 call =
new Sleep (context);
5909 else if (name ==
"#sqrt")
5913 else if (name ==
"#string")
5921 call =
new Tan (context);
5923 else if (name ==
"#to_buffer")
5927 else if (name ==
"#to_double")
5931 else if (name ==
"#to_doubles")
5935 else if (name ==
"#to_host_dirs")
5939 else if (name ==
"#to_integer")
5943 else if (name ==
"#to_integers")
5947 else if (name ==
"#to_string")
5951 else if (name ==
"#type")
5953 call =
new Type (context);
5957 if (name ==
"#write_file")
5969 "madara::expression::Interpreter: " 5970 "System call %s is unsupported in this version of MADARA, " 5971 "defaulting to print_system_calls help menu.\n", name.c_str ());
5974 "System call %s does not exist.");
5981 bool handled =
false;
5983 ::std::list<Symbol *> param_list;
5988 handle_parenthesis (context, input, i, lastValidInput, handled,
5989 accumulated_precedence, param_list,
true);
5991 call->
nodes_.resize (param_list.size ());
5994 for (::std::list<Symbol *>::iterator arg = param_list.begin ();
5995 arg != param_list.end (); ++arg, ++cur)
5997 call->
nodes_[cur] = (*arg)->build ();
6000 precedence_insert (context, call, list);
6006 "madara::expression::Interpreter: " 6007 "KARL COMPILE ERROR: System call ";
6009 message +=
" does not have appropriate parentheses\n";
6023 std::string::size_type &i,
6024 int & accumulated_precedence,
6025 ::std::list<madara::expression::Symbol *>& list,
6032 std::string::size_type j = 1;
6035 for (; i + j <= input.length () && is_number (input[i + j]); ++j)
6039 if ((i + j <= input.length () && input[i + j] ==
'.') || input[i] ==
'.')
6041 if (input[i] !=
'.')
6044 for (; i + j <= input.length () && is_number (input[i + j]); ++j)
6048 if (i + j <= input.length () &&
6049 (input[i + j] ==
'e' || input[i + j] ==
'E'))
6052 if (i + j <= input.length () &&
6053 (input[i + j] ==
'+' || input[i + j] ==
'-'))
6058 for (; i + j <= input.length () && is_number (input[i + j]); ++j)
6064 std::stringstream buffer;
6065 buffer << input.substr (i, j);
6066 buffer >> new_number;
6076 std::stringstream buffer;
6077 buffer << input.substr (i, j);
6078 buffer >> new_number;
6085 lastValidInput = number;
6091 precedence_insert (context, number, list);
6100 ::std::list<madara::expression::Symbol *>& list)
6106 Symbol *parent = list.back ();
6120 for (child = parent->
right_;
6124 grandparent = parent;
6132 if (child && (child_operator == 0 && child_ternary == 0))
6135 "Interpreter::precedence_insert: " 6136 "Level 1: child is neither an operator or ternary\n");
6141 if (op_assignment || op_implies || op_unary)
6151 for (child = parent->
right_;
6155 grandparent = parent;
6160 child_operator = dynamic_cast <
Operator *> (child);
6163 if (child && (child_operator == 0 && child_ternary == 0))
6166 "Interpreter::precedence_insert: " 6167 "Level 2: child is neither an operator or ternary\n");
6177 (op_assignment || op_implies || op_unary)))
6188 if (parent_binary && !parent->
left_)
6191 Both * parent_both = dynamic_cast <
Both *> (parent);
6195 "KARL COMPILE WARNING: Empty statements between ';' may" 6196 " cause slower execution, attempting to prune away the extra " 6202 "madara::expression::Interpreter: " 6203 "KARL COMPILE WARNING: Binary operation has no left child. " 6204 "Inserting a zero\n");
6214 if (parent_unary && parent->
left_)
6217 "madara::expression::Interpreter: " 6218 "KARL COMPILE ERROR: Unary operation shouldn't have a left child\n");
6221 "KARL COMPILE ERROR: " 6222 "Parent unary node has a left child, shouldn't be possible\n");
6235 "madara::expression::Interpreter: " 6236 "KARL COMPILE ERROR: unary operation shouldn't have a left child\n");
6239 "KARL COMPILE ERROR: " 6240 "Unary node has a left child, shouldn't be possible\n");
6245 "Interpreter::precedence_insert: " 6246 "Level 3: op is setting its left to the existing child\n");
6253 "Interpreter::precedence_insert: " 6254 "Level 3: parent->right is being set to current operator\n");
6267 grandparent->
right_ = op;
6271 list.push_back (op);
6277 list.push_back (op);
6284 const std::string &input, std::string::size_type &i,
6286 bool & handled,
int & accumulated_precedence,
6287 ::std::list<madara::expression::Symbol *>& list,
6288 bool build_argument_list)
6291 if (is_number (input[i]) ||
6292 (i + 1 < input.size () && input[i] ==
'.' && is_number (input[i+1])))
6296 number_insert (context, input, i, accumulated_precedence,
6297 list, lastValidInput);
6299 else if (is_alphanumeric (input[i]))
6303 variable_insert (context, input, i, accumulated_precedence,
6304 list, lastValidInput);
6306 else if (is_string_literal (input[i]))
6308 char opener = input[i];
6312 string_insert (opener, context, input, i, accumulated_precedence,
6313 list, lastValidInput);
6315 else if (i < input.length () && input[i] ==
'[')
6319 object->add_precedence (accumulated_precedence);
6323 ::std::list<Symbol *> param_list;
6325 int local_precedence = 0;
6326 Symbol * local_last_valid = 0;
6331 handle_array (context, input, i, local_last_valid, handled,
6332 local_precedence, param_list);
6334 object->nodes_.resize (param_list.size ());
6337 for (::std::list<Symbol *>::iterator arg = param_list.begin ();
6338 arg != param_list.end (); ++arg, ++cur)
6340 object->nodes_[cur] = (*arg)->build ();
6343 precedence_insert (context,
object, list);
6346 else if (input[i] ==
'#')
6350 system_call_insert (context, input, i, accumulated_precedence,
6351 list, lastValidInput);
6353 else if (input[i] ==
'+')
6359 if (i + 1 < input.size () && input[i + 1] ==
'+')
6365 else if (i + 1 < input.size () && input[i + 1] ==
'=')
6369 if (var || array_ref)
6377 "madara::expression::Interpreter: " 6378 "KARL COMPILE ERROR (+=): " 6379 "Assignments must have a variable left hand side.\n");
6382 "KARL COMPILE ERROR (+=): " 6383 "Assignments must have a variable left hand side");
6393 precedence_insert (context, op, list);
6396 else if (input[i] ==
'-')
6402 if (i + 1 < input.size () && input[i + 1] ==
'-')
6408 else if (i + 1 < input.size () && input[i + 1] ==
'=')
6412 if (var || array_ref)
6420 "madara::expression::Interpreter: " 6421 "KARL COMPILE ERROR (-=): " 6422 "Assignments must have a variable left hand side.\n");
6425 "KARL COMPILE ERROR (-=): " 6426 "Assignments must have a variable left hand side");
6431 else if (i + 1 < input.size () && is_number (input[i + 1]))
6435 number_insert (context, input, i, accumulated_precedence,
6436 list, lastValidInput);
6439 else if (!lastValidInput)
6450 precedence_insert (context, op, list);
6454 else if (input[i] ==
'*')
6460 if (i + 1 < input.size () && input[i + 1] ==
'=')
6464 if (var || array_ref)
6472 "madara::expression::Interpreter: " 6473 "KARL COMPILE ERROR (*=): " 6474 "Assignments must have a variable left hand side.\n");
6477 "KARL COMPILE ERROR (*=): " 6478 "Assignments must have a variable left hand side");
6489 precedence_insert (context, op, list);
6492 else if (input[i] ==
'%')
6501 precedence_insert (context, op, list);
6504 else if (input[i] ==
'/')
6507 if (i + 1 < input.size () && input[i + 1] ==
'/')
6510 for (; i < input.size () && input[i] !=
'\n'; ++i);
6513 else if (i + 1 < input.size () && input[i + 1] ==
'*')
6516 std::string::size_type found = input.find (
"*/", i + 1);
6520 if (found != std::string::npos)
6536 if (i + 1 < input.size () && input[i + 1] ==
'=')
6540 if (var || array_ref)
6547 "madara::expression::Interpreter: " 6548 "KARL COMPILE ERROR (/=): " 6549 "Assignments must have a variable left hand side.\n");
6552 "KARL COMPILE ERROR (/=): " 6553 "Assignments must have a variable left hand side");
6562 precedence_insert (context, op, list);
6566 else if (input[i] ==
'=')
6572 if (i + 1 < input.size () && input[i + 1] ==
'=')
6581 precedence_insert (context, op, list);
6584 else if (i + 1 < input.size () && input[i + 1] ==
'>')
6593 precedence_insert (context, op, list);
6605 precedence_insert (context, op, list);
6609 else if (input[i] ==
'!')
6615 if (i + 1 < input.size () && input[i + 1] ==
'=')
6629 precedence_insert (context, op, list);
6633 else if ((uint8_t)input[i] == 251)
6643 precedence_insert (context, op, list);
6646 else if (input[i] ==
'&')
6649 if (i + 1 < input.size () && input[i + 1] ==
'&')
6658 precedence_insert (context, op, list);
6664 "madara::expression::Interpreter: " 6665 "KARL COMPILE ERROR: " 6666 "Logical And (&) not available. " \
6667 "You may want to use && instead in %s.\n", input.c_str ());
6670 "KARL COMPILE ERROR: " 6671 "Logical And (&) not available.");
6675 else if (input[i] ==
'|')
6678 if (i + 1 < input.size () && input[i + 1] ==
'|')
6687 precedence_insert (context, op, list);
6693 "KARL COMPILE ERROR: " 6694 "Logical Or (|) not available. " \
6695 "You may want to use || instead in %s.\n", input.c_str ());
6698 "KARL COMPILE ERROR: " 6699 "Logical Or (|) not available.");
6703 else if (input[i] ==
';')
6709 if (i + 1 < input.size () && input[i + 1] ==
'>')
6722 precedence_insert (context, op, list);
6725 else if (input[i] ==
',')
6727 if (build_argument_list)
6736 precedence_insert (context, op, list);
6739 else if (input[i] ==
'<')
6745 if (i + 1 < input.size () && input[i + 1] ==
'=')
6757 precedence_insert (context, op, list);
6760 else if (input[i] ==
'>')
6766 if (i + 1 < input.size () && input[i + 1] ==
'=')
6778 precedence_insert (context, op, list);
6781 else if (input[i] ==
'(')
6785 handle_parenthesis (context, input, i, lastValidInput,
6786 handled, accumulated_precedence, list);
6788 else if (input[i] ==
'\t' || input[i] ==
' ' 6789 || input[i] ==
'\r' || input[i] ==
'\n')
6801 const std::string &input, std::string::size_type &i,
6803 bool & handled,
int & accumulated_precedence,
6804 ::std::list<madara::expression::Symbol *>& master_list)
6811 int initial_precedence = accumulated_precedence;
6813 ::std::list<Symbol *> list;
6816 bool closed =
false;
6817 while (i < input.length ())
6819 main_loop (context, input, i, lastValidInput,
6820 handled, accumulated_precedence, list,
true);
6822 if (input[i] ==
']')
6830 else if (input[i] ==
',')
6833 while (list.size ())
6835 master_list.push_back (list.back ());
6838 accumulated_precedence = initial_precedence;
6840 else if (i == input.length () - 1)
6849 "madara::expression::Interpreter: " 6850 "KARL COMPILE ERROR: " 6851 "Forgot to close parenthesis in %s.\n", input.c_str ());
6854 if (list.size () > 0)
6856 if (list.size () > 1)
6859 "madara::expression::Interpreter: " 6860 "KARL COMPILE ERROR: " 6861 "A parenthesis was closed, leaving multiple list items (there should " 6862 "be a max of 1) in %s.\n", input.c_str ());
6865 while (list.size ())
6867 master_list.push_back (list.back ());
6880 const std::string &input, std::string::size_type &i,
6882 bool & handled,
int & accumulated_precedence,
6883 ::std::list<madara::expression::Symbol *>& master_list,
6884 bool build_argument_list)
6891 int initial_precedence = accumulated_precedence;
6893 ::std::list<Symbol *> list;
6896 bool closed =
false;
6897 while (i < input.length ())
6899 main_loop (context, input, i, lastValidInput,
6900 handled, accumulated_precedence, list, build_argument_list);
6902 if (input[i] ==
')')
6910 else if (build_argument_list && input[i] ==
',')
6913 while (list.size ())
6915 master_list.push_back (list.back ());
6918 accumulated_precedence = initial_precedence;
6920 else if (i == input.length () - 1)
6926 if (!build_argument_list && !closed)
6929 "madara::expression::Interpreter: " 6930 "KARL COMPILE ERROR: " 6931 "Forgot to close parenthesis in %s.\n", input.c_str ());
6934 if (!build_argument_list && master_list.size () > 0 && list.size () > 0)
6936 Symbol * lastSymbol = master_list.back ();
6945 precedence_insert (context, list.back (), master_list);
6953 else if (list.size () > 0)
6955 if (list.size () > 1)
6958 "madara::expression::Interpreter: " 6959 "KARL COMPILE ERROR: " 6960 "A parenthesis was closed, leaving multiple list items (there should " 6961 "be a max of 1) in %s.\n", input.c_str ());
6964 while (list.size ())
6966 master_list.push_back (list.back ());
6982 ExpressionTreeMap::const_iterator found = cache_.find (input);
6983 if (found != cache_.end ())
6984 return found->second;
6986 ::std::list<Symbol *> list;
6988 Symbol * lastValidInput = 0;
6989 bool handled =
false;
6990 int accumulated_precedence = 0;
6991 std::string::size_type last_i = 0;
6993 for (std::string::size_type i = 0;
6994 i < input.length ();)
6999 main_loop (context, input, i, lastValidInput,
7000 handled, accumulated_precedence, list);
7004 size_t start = i > 10 ? i - 10 : 0;
7005 size_t end = input.size () - i > 10 ? i + 10 : input.size ();
7007 std::string snippet = input.substr (start, end - start);
7011 "madara::expression::Interpreter: " 7013 "Compilation is spinning at %d in %s. Char is %c. Breaking out.\n",
7014 (int)i, snippet.c_str (), input[i]);
7035 list.back ()->build (),
false);
7039 delete list.back ();
7042 cache_[input] = tree;
7051 #endif // _MADARA_NO_KARL_ 7053 #endif // _INTERPRETER_CPP_ Calculates a base term taken to a power.
This class encapsulates an entry in a KnowledgeBase.
virtual ComponentNode * build(void)
builds an equivalent ExpressionTree node
virtual ~ReturnRight(void)
destructor
virtual ~Preincrement(void)
destructor
madara::knowledge::ThreadSafeContext & context_
Context for variables.
VariableDecrement(Symbol *lhs, madara::knowledge::KnowledgeRecord value, Symbol *rhs, madara::knowledge::ThreadSafeContext &context)
constructors
ExpressionTree interpret(madara::knowledge::ThreadSafeContext &context, const std::string &input)
Compiles an expression into an expression tree.
TernaryOperator(logger::Logger &logger, Symbol *left, Symbol *right, int precedence_=1)
constructor
virtual ~Assignment(void)
destructor
virtual ~VariableDivide(void)
destructor
Sets the system clock or a variable clock.
virtual ~Symbol(void)
destructor
virtual int add_precedence(int accumulated_precedence)
returns the precedence level
ToString(madara::knowledge::ThreadSafeContext &context_)
constructor
Fragment(madara::knowledge::ThreadSafeContext &context_)
constructor
virtual ~Not(void)
destructor
virtual ComponentNode * build(void)
builds an equivalent ExpressionTree node
virtual ComponentNode * build(void)
builds an equivalent ExpressionTree node
Postincrement node of the parse tree.
virtual ComponentNode * build(void)
builds an equivalent ExpressionTree node
virtual ~ExpandEnv(void)
destructor
Returns the square root of a term.
virtual ~LessThan(void)
destructor
virtual ~Or(void)
destructor
std::vector< Symbol * > Symbols
Returns the time in nanoseconds since epoch.
Evaluates both left and right children, regardless of values.
virtual ComponentNode * build(void)
builds an equivalent ExpressionTree node
ToHostDirs(madara::knowledge::ThreadSafeContext &context_)
constructor
virtual ComponentNode * build(void)
builds an equivalent ExpressionTree node
virtual ~Isinf(void)
destructor
virtual ComponentNode * build(void)
builds an equivalent ExpressionTree node
WriteFile(madara::knowledge::ThreadSafeContext &context_)
constructor
virtual int add_precedence(int accumulated_precedence)
returns the precedence level
Equality(logger::Logger &logger)
constructor
Returns the type of a specified knowledge record.
virtual int add_precedence(int accumulated_precedence)
returns the precedence level
Composite node that divides a variable by some right hand side.
Sleeps for a certain amount of time.
virtual ComponentNode * build(void)
builds an equivalent ExpressionTree node
Returns the cosine of a term (radians)
Function node of the parse tree.
Defines a terminal node of that references the current value stored in a variable.
A composite node that increments a right expression.
virtual ~ClearVariable(void)
destructor
Returns the cosine of a term in radians.
Returns whether the first argument is an infinite number.
Sets the output format to use std::scientific.
virtual ~UnaryOperator(void)
destructor
virtual int add_precedence(int accumulated_precedence)
returns the precedence level
virtual ~Modulus(void)
destructorm
Converts an argument to an array of doubles.
Type(madara::knowledge::ThreadSafeContext &context_)
constructor
virtual ~Size(void)
destructor
Defines a terminal node of that references the current value stored in a variable.
VariableMultiply(Symbol *lhs, madara::knowledge::KnowledgeRecord value, Symbol *rhs, madara::knowledge::ThreadSafeContext &context)
constructors
virtual int add_precedence(int accumulated_precedence)
returns the precedence level
Check and left and right arguments for equality.
virtual int add_precedence(int accumulated_precedence)
returns the precedence level
Division node of the parse tree.
madara::knowledge::ThreadSafeContext & context_
Context for variables.
virtual ~WriteFile(void)
destructor
virtual int add_precedence(int accumulated_precedence)
returns the precedence level
A composite node that encompasses addition of two expressions.
Expands a statement, e.g.
Encapsulates a MADARA KaRL expression into an evaluatable tree.
virtual ~ToIntegers(void)
destructor
Abstract base class for operators with 3+ potential subnodes.
A composite node that compares left and right children for inequality.
GetClock(madara::knowledge::ThreadSafeContext &context_)
constructor
virtual int add_precedence(int accumulated_precedence)
returns the precedence level
Check and left and right arguments for less than or equal to.
virtual ComponentNode * build(void)
builds an equivalent ExpressionTree node
Returns a random integer.
SquareRootUnary(logger::Logger &logger)
constructor
virtual int add_precedence(int accumulated_precedence)
returns the precedence level
Check and left and right arguments for less than.
virtual ~ToInteger(void)
destructor
Addition node of the parse tree.
Print(madara::knowledge::ThreadSafeContext &context_)
constructor
Returns a version that has a directory structure appropriate to the OS.
virtual ComponentNode * build(void)
builds an equivalent ExpressionTree node
List(madara::knowledge::ThreadSafeContext &context)
constructors
ForLoop(Symbol *precondition, Symbol *condition, Symbol *postcondition, Symbol *body, madara::knowledge::ThreadSafeContext &context)
constructor
And(logger::Logger &logger)
constructor
virtual ~Equality(void)
destructor
std::deque< ComponentNode * > ComponentNodes
a vector of Component Nodes
Composite node that subtracts a variable by some right hand side.
Interpreter()
Constructor.
virtual ComponentNode * build(void)
builds an equivalent ExpressionTree node
A composite node that encompasses subtraction of a right expression from a left expression.
Cos(madara::knowledge::ThreadSafeContext &context_)
constructor
virtual int add_precedence(int accumulated_precedence)
returns the precedence level
Assign the value of an expression to a variable.
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...
virtual ~SquareRootUnary(void)
destructor
A composite node that compares left and right expressions for greater than or equal to...
virtual ComponentNode * build(void)
builds an equivalent ExpressionTree node
Generates a random double.
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. ...
virtual int add_precedence(int accumulated_precedence)
returns the precedence level
virtual ComponentNode * build(void)
builds an equivalent ExpressionTree node
virtual ~Sleep(void)
destructor
virtual int add_precedence(int accumulated_precedence)
returns the precedence level
Converts an argument to a string.
Postincrement(logger::Logger &logger)
constructor
Returns the expansion of a statement.
virtual ~GetTime(void)
destructor
virtual int add_precedence(int accumulated_precedence)
returns the precedence level
A composite node that multiplies a left expression by a right expression.
RandDouble(madara::knowledge::ThreadSafeContext &context_)
constructor
virtual ~VariableMultiply(void)
destructor
A composite node that evaluates both left and right expressions regardless of their evaluations...
A composite node that takes the square root of a term.
virtual int add_precedence(int accumulated_precedence)
returns the precedence level
virtual ~Both(void)
destructor
virtual ~Fragment(void)
destructor
virtual ~ExpandStatement(void)
destructor
virtual ~SystemCall(void)
destructor
virtual int add_precedence(int accumulated_precedence)
returns the precedence level
virtual ComponentNode * build(void)
builds an equivalent ExpressionTree node
Modulus node of the parse tree (10 % 4 == 2)
virtual int add_precedence(int accumulated_precedence)
returns the precedence level
virtual int add_precedence(int accumulated_precedence)
returns the precedence level
virtual ComponentNode * build(void)
builds an equivalent ExpressionTree node
A composite node that decrements a left expression.
virtual ~ToDoubles(void)
destructor
Check and left and right arguments for inequality.
Returns the sin of a term in radians.
virtual ComponentNode * build(void)
builds an equivalent ExpressionTree node
A composite node that performs an implication (inference rule)
A composite node that decrements a right expression.
Reads or sets the MADARA log level.
virtual int add_precedence(int accumulated_precedence)
returns the precedence level
Sets the output format to std::fixed.
virtual ComponentNode * build(void)
builds an equivalent ExpressionTree node
virtual int add_precedence(int accumulated_precedence)
returns the precedence level
This class stores variables and their values for use by any entity needing state information in a thr...
virtual ComponentNode * build(void)
builds an equivalent ExpressionTree node
Attempts to clear a variable.
ArrayRef(const std::string &key, Symbol *index, madara::knowledge::ThreadSafeContext &context)
constructors
madara::knowledge::KnowledgeRecord value_
value can be faster than rhs_, so use it if possible
virtual int add_precedence(int accumulated_precedence)
returns the precedence level
void precedence_insert(madara::knowledge::ThreadSafeContext &context, Symbol *op,::std::list< Symbol * > &list)
Inserts a mathematical operator into the tree.
virtual ComponentNode * build(void)
builds an equivalent ExpressionTree node
virtual int add_precedence(int accumulated_precedence)
returns the precedence level
virtual ComponentNode * build(void)
builds an equivalent ExpressionTree node
Returns the clock of the argument or the system clock.
Attempts to delete a variable.
GetTime(madara::knowledge::ThreadSafeContext &context_)
constructor
virtual ComponentNode * build(void)
builds an equivalent ExpressionTree node
Returns a fragment of the knowledge record.
madara::knowledge::KnowledgeRecord prune(void)
Prunes the expression tree of unnecessary nodes.
Prints a Knowledge Record to the stderr.
virtual ComponentNode * build(void)
builds an equivalent ExpressionTree node
virtual ComponentNode * build(void)
builds an equivalent ExpressionTree node
virtual ComponentNode * build(void)
builds an equivalent ExpressionTree node
void main_loop(madara::knowledge::ThreadSafeContext &context, const std::string &input, std::string::size_type &i, Symbol *&lastValidInput, bool &handled, int &accumulated_precedence,::std::list< Symbol * > &list, bool build_argument_list=false)
Inserts a variable into the tree.
virtual int add_precedence(int accumulated_precedence)
returns the precedence level
A composite node that evaluates both left and right expressions regardless of their evaluations...
Number(logger::Logger &logger, std::string input)
constructors
Postdecrement(logger::Logger &logger)
constructor
VariableCompare(Symbol *lhs, madara::knowledge::KnowledgeRecord value, Symbol *rhs, int compare_type, madara::knowledge::ThreadSafeContext &context)
constructors
virtual ~GreaterThan(void)
destructor
virtual int add_precedence(int accumulated_precedence)
returns the precedence level
virtual ComponentNode * build(void)
builds an equivalent ExpressionTree node
virtual ~SetClock(void)
destructor
A composite node that calls a function.
virtual int add_precedence(int accumulated_precedence)
returns the precedence level
virtual ComponentNode * build(void)
builds an equivalent ExpressionTree node
Defines a node that contains a madara::knowledge::KnowledgeRecord::Integer value. ...
virtual int add_precedence(int accumulated_precedence)
returns the precedence level
Provides knowledge logging services to files and terminals.
virtual int add_precedence(int accumulated_precedence)
returns the precedence level
virtual ~Power(void)
destructor
virtual int add_precedence(int accumulated_precedence)
returns the precedence level
virtual int add_precedence(int accumulated_precedence)
returns the precedence level
virtual ~DeleteVariable(void)
destructor
virtual ComponentNode * build(void)
builds an equivalent ExpressionTree node
madara::knowledge::ThreadSafeContext & context_
#define madara_logger_log(logger, level,...)
Fast version of the madara::logger::log method.
Writes a knowledge record to an user-specified file name.
virtual int add_precedence(int accumulated_precedence)
returns the precedence level
Converts an argument into an unsigned char buffer.
virtual ComponentNode * build(void)
builds an equivalent ExpressionTree node
virtual ~VariableDecrement(void)
destructor
Returns the type of a specified knowledge record.
Returns a base term taken to a power (exponent)
Operator(logger::Logger &logger, Symbol *left, Symbol *right, int precedence_=1)
constructor
virtual ~Eval(void)
destructor
VariableIncrement(Symbol *lhs, madara::knowledge::KnowledgeRecord value, Symbol *rhs, madara::knowledge::ThreadSafeContext &context)
constructors
GreaterThanEqual(logger::Logger &logger)
constructor
virtual ComponentNode * build(void)
builds an equivalent ExpressionTree node
Predecrement(logger::Logger &logger)
constructor
virtual ComponentNode * build(void)
builds an equivalent ExpressionTree node
Multiply(logger::Logger &logger)
constructor
virtual ComponentNode * build(void)
builds an equivalent ExpressionTree node
virtual ComponentNode * build(void)
builds an equivalent ExpressionTree node
virtual ComponentNode * build(void)
builds an equivalent ExpressionTree node
Postdecrement node of the parse tree.
Divide a variable by a certain amount.
SetScientific(madara::knowledge::ThreadSafeContext &context_)
constructor
Abstract base class for all parse tree node operators.
madara::knowledge::KnowledgeRecord value_
value can be faster than rhs_, so use it if possible
Sets or returns the current MADARA logging level.
virtual int add_precedence(int accumulated_precedence)
returns the precedence level
virtual ~SetFixed(void)
destructor
Sequence(logger::Logger &logger)
constructor
Returns the size of a specified knowledge record.
virtual ~SetPrecision(void)
destructor
Returns the tangent of a term (radians)
SquareRoot(madara::knowledge::ThreadSafeContext &context_)
constructor
LessThan(logger::Logger &logger)
constructor
virtual ComponentNode * build(void)
builds an equivalent ExpressionTree node
A multi-threaded logger for logging to one or more destinations.
virtual ~SquareRoot(void)
destructor
virtual int add_precedence(int accumulated_precedence)
returns the precedence level
void set_value(const KnowledgeRecord &new_value)
Sets the value from another KnowledgeRecord, does not copy clock and write_quality.
virtual ComponentNode * build(void)
builds an equivalent ExpressionTree node
Power(madara::knowledge::ThreadSafeContext &context_)
constructor
virtual ComponentNode * build(void)
builds an equivalent ExpressionTree node
A composite node that performs a logical and.
virtual ComponentNode * build(void)
builds an equivalent ExpressionTree node
Returns the size of a record.
virtual ~ToBuffer(void)
destructor
Returns the expansion of a statement with environment vars.
virtual ~ToHostDirs(void)
destructor
virtual int add_precedence(int accumulated_precedence)
returns the precedence level
virtual ~Sequence(void)
destructor
virtual ~ForLoop(void)
destructor
Evaluates both left and right children, regardless of values.
virtual ComponentNode * build(void)
builds an equivalent ExpressionTree node
GreaterThan(logger::Logger &logger)
constructor
SetPrecision(madara::knowledge::ThreadSafeContext &context_)
constructor
Predecrement node of the parse tree.
Converts an argument to an array of integers.
virtual ComponentNode * build(void)
builds an equivalent ExpressionTree node
Or(logger::Logger &logger)
constructor
void number_insert(madara::knowledge::ThreadSafeContext &context, const std::string &input, std::string::size_type &i, int &accumulated_precedence,::std::list< Symbol * > &list, Symbol *&lastValidInput)
Inserts a number into the tree.
void string_insert(char opener, madara::knowledge::ThreadSafeContext &context, const std::string &input, std::string::size_type &i, int &accumulated_precedence,::std::list< Symbol * > &list, Symbol *&lastValidInput)
Inserts a variable into the tree.
Fragment the Knowledge Record.
virtual int add_precedence(int accumulated_precedence)
returns the precedence level
virtual int add_precedence(int accumulated_precedence)
returns the precedence level
virtual int add_precedence(int accumulated_precedence)
returns the precedence level
Sets the system or a variable clock.
virtual int add_precedence(int accumulated_precedence)
returns the precedence level
virtual ~RandDouble(void)
destructor
virtual ComponentNode * build(void)
builds an equivalent ExpressionTree node
virtual ComponentNode * build(void)
builds an equivalent ExpressionTree node
virtual ComponentNode * build(void)
builds an equivalent ExpressionTree node
virtual ~Number(void)
destructor
virtual ComponentNode * build(void)
builds an equivalent ExpressionTree node
virtual int add_precedence(int accumulated_precedence)
returns the precedence level
virtual ComponentNode * build(void)
builds an equivalent ExpressionTree node
Returns the square root of a term.
Composite node that multiplies a variable by some right hand side.
Sleep(madara::knowledge::ThreadSafeContext &context_)
constructor
Symbol(logger::Logger &logger, Symbol *left, Symbol *right, int precedence_=0)
constructor
virtual ComponentNode * build(void)=0
abstract method for building an Expression ExpressionTree Node
virtual ~TernaryOperator(void)
destructor
virtual int add_precedence(int accumulated_precedence)
returns the precedence level
virtual int add_precedence(int accumulated_precedence)
returns the precedence level
Check and left and right arguments for greater than.
int compare_type_
type of comparison. See madara/Globals.h
virtual int add_precedence(int accumulated_precedence)
returns the precedence level
ReturnRight(logger::Logger &logger)
constructor
virtual int add_precedence(int accumulated_precedence)
returns the precedence level
virtual int add_precedence(int accumulated_precedence)
returns the precedence level
A composite node that compares left and right expressions for equality.
Returns the current time in seconds since epoch.
Subtract(logger::Logger &logger)
constructor
virtual ~GetTimeSeconds(void)
destructor
Prints all supported system calls.
virtual ComponentNode * build(void)
builds an equivalent ExpressionTree node
Symbol * rhs_
rhs is used for complex rhs types (not a simple number)
Divide(logger::Logger &logger)
constructor
#define madara_logger_ptr_log(logger, level,...)
Fast version of the madara::logger::log method for Logger pointers.
virtual ComponentNode * build(void)
builds an equivalent ExpressionTree node
Preincrement(logger::Logger &logger)
constructor
virtual int add_precedence(int accumulated_precedence)
returns the precedence level
madara::knowledge::ThreadSafeContext & context_
A composite node that increments a right expression.
Converts an argument to a double.
virtual int add_precedence(int accumulated_precedence)
returns the precedence level
const std::string key_
Key for retrieving value of this variable.
Evaluates a knowledge::KnowledgeRecord and returns the evaluation result.
Sleeps for a certain amount of time.
ClearVariable(madara::knowledge::ThreadSafeContext &context_)
constructor
virtual ComponentNode * build(void)
builds an equivalent ExpressionTree node
SystemCall(madara::knowledge::ThreadSafeContext &context_)
constructor
virtual ComponentNode * build(void)
builds an equivalent ExpressionTree node
virtual ~ArrayRef(void)
destructor
Abstract base class of all parse tree nodes.
virtual int add_precedence(int accumulated_precedence)
returns the precedence level
virtual ComponentNode * build(void)
builds an equivalent ExpressionTree node
virtual ~PrintSystemCalls(void)
destructor
virtual ComponentNode * build(void)
builds an equivalent ExpressionTree node
Both(logger::Logger &logger)
constructor
Sets the double precision for converting doubles to a string and for printing.
ToDoubles(madara::knowledge::ThreadSafeContext &context_)
constructor
Negate node of the parse tree.
virtual ~ToDouble(void)
destructor
virtual ComponentNode * build(void)
builds an equivalent ExpressionTree node
Isinf(madara::knowledge::ThreadSafeContext &context_)
constructor
Modulus(logger::Logger &logger)
constructor
virtual ~GetClock(void)
destructor
A composite node that logically nots a right expression.
A composite node that allows for variable assignment.
virtual int add_precedence(int accumulated_precedence)
returns the precedence level
virtual int add_precedence(int accumulated_precedence)
returns the precedence level
A composite node that compares left and right children for greater than.
Returns the system clock or a variable clock.
virtual ComponentNode * build(void)
builds an equivalent ExpressionTree node
Returns the type of a record.
ToBuffer(madara::knowledge::ThreadSafeContext &context_)
constructor
logger::Logger * logger_
left and right pointers
Tan(madara::knowledge::ThreadSafeContext &context_)
constructor
Returns the wall clock time in seconds.
Add(logger::Logger &logger)
constructor
Assign the value of an expression to a variable.
madara::knowledge::KnowledgeRecord::Integer Integer
madara::knowledge::ThreadSafeContext & context_
virtual ~ReadFile(void)
destructor
virtual ~Function(void)
destructor
An abstract base class defines a simple abstract implementation of an expression tree node...
virtual ~Variable(void)
destructor
void handle_parenthesis(madara::knowledge::ThreadSafeContext &context, const std::string &input, std::string::size_type &i, Symbol *&lastValidInput, bool &handled, int &accumulated_precedence,::std::list< Symbol * > &list, bool build_argument_list=false)
Handles a parenthesis.
Preincrement node of the parse tree.
ConstArray(madara::knowledge::ThreadSafeContext &context)
constructor
virtual int add_precedence(int accumulated_precedence)
returns the precedence level
Returns the tangent of a term in radians.
Logically and node of the parse tree.
LessThanEqual(logger::Logger &logger)
constructor
virtual int add_precedence(int accumulated_precedence)
returns the precedence level
A composite node that integrally negates a right expression.
virtual ~Negate(void)
destructor
LogLevel(madara::knowledge::ThreadSafeContext &context_)
constructor
virtual ComponentNode * build(void)
builds an equivalent ExpressionTree node
Negate(logger::Logger &logger)
constructor
void system_call_insert(madara::knowledge::ThreadSafeContext &context, const std::string &input, std::string::size_type &i, int &accumulated_precedence,::std::list< Symbol * > &list, Symbol *&lastValidInput)
Inserts a system call into the tree.
virtual ~Postdecrement(void)
destructor
virtual ComponentNode * build(void)
builds an equivalent ExpressionTree node
virtual int add_precedence(int accumulated_precedence)
returns the precedence level
Returns the wall clock time.
A composite node that contains an array of values.
VariableDivide(Symbol *lhs, madara::knowledge::KnowledgeRecord value, Symbol *rhs, madara::knowledge::ThreadSafeContext &context)
constructors
virtual int add_precedence(int accumulated_precedence)
returns the precedence level
virtual int add_precedence(int accumulated_precedence)
returns the precedence level
Implies(logger::Logger &logger)
constructor
virtual int add_precedence(int accumulated_precedence)
returns the precedence level
virtual ~Implies(void)
destructor
madara::knowledge::ThreadSafeContext & context_
Context for variables.
virtual ComponentNode * build(void)
builds an equivalent ExpressionTree node
madara::knowledge::ThreadSafeContext & context_
Context for variables.
virtual ComponentNode * build(void)
builds an equivalent ExpressionTree node
An exception for unrecoverable KaRL compilation issues.
virtual ComponentNode * build(void)
builds an equivalent ExpressionTree node
UnaryOperator(logger::Logger &logger, Symbol *right, int precedence_=1)
constructor
Eval(madara::knowledge::ThreadSafeContext &context_)
constructor
virtual ComponentNode * build(void)
builds an equivalent ExpressionTree node
Clears a variable in the knowledge base.
virtual int add_precedence(int accumulated_precedence)
returns the precedence level
madara::knowledge::ThreadSafeContext & context_
Context for variables.
Sets the precision of doubles.
Deletes a variable from the knowledge base.
virtual int add_precedence(int accumulated_precedence)
returns the precedence level
Function(const std::string &name, madara::knowledge::ThreadSafeContext &context)
constructor
virtual ~RandInt(void)
destructor
virtual ~Subtract(void)
destructor
virtual ComponentNode * build(void)
builds an equivalent ExpressionTree node
virtual int add_precedence(int accumulated_precedence)
returns the precedence level
virtual ~GreaterThanEqual(void)
destructor
virtual int add_precedence(int accumulated_precedence)
returns the precedence level
RandInt(madara::knowledge::ThreadSafeContext &context_)
constructor
Sets the output format to use std::fixed.
virtual int add_precedence(int accumulated_precedence)
returns the precedence level
virtual ComponentNode * build(void)
builds an equivalent ExpressionTree node
virtual ~Postincrement(void)
destructor
Logically or node of the parse tree.
Abstract base class for operators with 3+ potential subnodes.
virtual ComponentNode * build(void)
builds an equivalent ExpressionTree node
SetClock(madara::knowledge::ThreadSafeContext &context_)
constructor
madara::knowledge::KnowledgeRecord value_
value can be faster than rhs_, so use it if possible
virtual int add_precedence(int accumulated_precedence)
returns the precedence level
void handle_for_loop(madara::knowledge::ThreadSafeContext &context, std::string &variable, const std::string &input, std::string::size_type &i, int &accumulated_precedence,::std::list< Symbol * > &list, Symbol *&returnableInput)
extracts precondition, condition, postcondition, and body from input
ExpandEnv(madara::knowledge::ThreadSafeContext &context_)
constructor
Sin(madara::knowledge::ThreadSafeContext &context_)
constructor
Variable(const std::string &key, madara::knowledge::ThreadSafeContext &context)
constructors
Returns the sin of a term (radians)
void handle_array(madara::knowledge::ThreadSafeContext &context, const std::string &input, std::string::size_type &i, Symbol *&lastValidInput, bool &handled, int &accumulated_precedence,::std::list< Symbol * > &list)
Handles a parenthesis.
virtual ~Sin(void)
destructor
virtual ~ConstArray(void)
destructor
virtual int add_precedence(int accumulated_precedence)
returns the precedence level
A composite node that performs a logical or.
virtual int add_precedence(int accumulated_precedence)
returns the precedence level
virtual ~Cos(void)
destructor
DeleteVariable(madara::knowledge::ThreadSafeContext &context_)
constructor
Subtraction node of the parse tree.
virtual ComponentNode * build(void)
builds an equivalent ExpressionTree node
virtual ~Divide(void)
destructor
virtual ComponentNode * build(void)
builds an equivalent ExpressionTree node
Increment a variable by a certain amount.
virtual int add_precedence(int accumulated_precedence)
returns the precedence level
Assignment(logger::Logger &logger)
constructor
virtual int add_precedence(int accumulated_precedence)
returns the precedence level
Ensures the directory delimiters are appropriate for the host operating system (e.g., on Windows, '\' and Linux, '/')
virtual ~Predecrement(void)
destructor
virtual ComponentNode * build(void)
builds an equivalent ExpressionTree node
Multiply a variable by a certain amount.
virtual int add_precedence(int accumulated_precedence)
returns the precedence level
madara::knowledge::KnowledgeRecord item_
contains the value of the leaf node
Reads a file from an user-provided file name.
Decrement a variable by a certain amount.
virtual ComponentNode * build(void)
builds an equivalent ExpressionTree node
virtual ~Add(void)
destructor
Size(madara::knowledge::ThreadSafeContext &context_)
constructor
A composite node that divides a left expression by a right one.
virtual ComponentNode * build(void)
builds an equivalent ExpressionTree node
ToIntegers(madara::knowledge::ThreadSafeContext &context_)
constructor
Evaluates a Knowledge Record and returns result.
virtual ~And(void)
destructor
Copyright (c) 2015 Carnegie Mellon University.
logger::Logger & get_logger(void) const
Gets the logger used for information printing.
virtual ~Tan(void)
destructor
Leaf node for an array reference.
virtual int add_precedence(int accumulated_precedence)
returns the precedence level
Sets the output to std::scientific.
Logically not the right node.
SetFixed(madara::knowledge::ThreadSafeContext &context_)
constructor
Expands a statement, e.g.
virtual int add_precedence(int accumulated_precedence)
returns the precedence level
Inequality(logger::Logger &logger)
constructor
virtual ComponentNode * build(void)
builds an equivalent ExpressionTree node
madara::knowledge::KnowledgeRecord value_
value can be faster than rhs_, so use it if possible
Defines a terminal node of that references the current value stored in a variable.
madara::knowledge::ThreadSafeContext & context_
Context for variables.
ToInteger(madara::knowledge::ThreadSafeContext &context_)
constructor
const std::string key_
Key for retrieving value of this variable.
virtual ~Print(void)
destructor
Increment a variable by a certain amount.
virtual ~Inequality(void)
destructor
GetTimeSeconds(madara::knowledge::ThreadSafeContext &context_)
constructor
Generates a random integer.
ReadFile(madara::knowledge::ThreadSafeContext &context_)
constructor
std::string to_string(const std::string &delimiter=", ") const
converts the value to a string.
virtual int add_precedence(int accumulated_precedence)
returns the precedence level
madara::knowledge::ThreadSafeContext & context_
Context for variables.
virtual ~LogLevel(void)
destructor
virtual int add_precedence(int accumulated_precedence)
returns the precedence level
virtual int add_precedence(int accumulated_precedence)
returns the precedence level
virtual ~VariableIncrement(void)
destructor
PrintSystemCalls(madara::knowledge::ThreadSafeContext &context_)
constructor
Evaluates both left and right children and returns right value.
virtual ~List(void)
destructor
virtual ComponentNode * build(void)
builds an equivalent ExpressionTree node
virtual ~Multiply(void)
destructor
Not(logger::Logger &logger)
constructor
virtual ComponentNode * build(void)
builds an equivalent ExpressionTree node
virtual int add_precedence(int accumulated_precedence)
returns the precedence level
Check and left and right arguments for greater than or equal to.
virtual ~Interpreter()
Destructor.
Prints a Knowledge Record.
virtual ComponentNode * build(void)
builds an equivalent ExpressionTree node
virtual ~SetScientific(void)
destructor
virtual ~ToString(void)
destructor
ExpandStatement(madara::knowledge::ThreadSafeContext &context_)
constructor
Converts an argument to an integer.
Defines a terminal node that contains a list.
virtual int add_precedence(int accumulated_precedence)
returns the precedence level
virtual int precedence(void)
abstract method for returning precedence level (higher value means higher precedence ...
ToDouble(madara::knowledge::ThreadSafeContext &context_)
constructor
virtual ~VariableCompare(void)
destructor
virtual int add_precedence(int accumulated_precedence)
returns the precedence level
Prints a help menu for all system calls.
virtual int add_precedence(int accumulated_precedence)=0
Defines a terminal node of that references the current value stored in a variable.
virtual ComponentNode * build(void)
builds an equivalent ExpressionTree node
virtual int add_precedence(int accumulated_precedence)
returns the precedence level
Multiplication node of the parse tree.
virtual ~Type(void)
destructor
virtual ~LessThanEqual(void)
destructor
A composite node that compares left and right children for less than.
Abstract base class for all parse tree node operators.
madara::knowledge::ThreadSafeContext & context_
Context for variables.
madara::knowledge::ThreadSafeContext & context_
Context for variables.
virtual ComponentNode * build(void)
builds an equivalent ExpressionTree node
virtual ~Operator(void)
destructor
A constant array that should not be changed.
Iterative looping node of the parse tree.
madara::knowledge::KnowledgeRecord value_
value can be faster than rhs_, so use it if possible
virtual ComponentNode * build(void)
builds an equivalent ExpressionTree node
void variable_insert(madara::knowledge::ThreadSafeContext &context, const std::string &input, std::string::size_type &i, int &accumulated_precedence,::std::list< Symbol * > &list, Symbol *&lastValidInput)
Inserts a variable into the tree.