From 8de2a1030e152af9655f9196765a5e1cae2eb8a3 Mon Sep 17 00:00:00 2001 From: Paul Beckingham Date: Sun, 28 Dec 2014 11:33:24 -0500 Subject: [PATCH] Eval - Reduced the verbosity of Eval under rc.debug.parser=3, improving readability. - Updated unit tests regarding modified debug output. --- src/Eval.cpp | 100 +++++++++++++++++++++++------------------------- test/bug.calc.t | 4 +- test/calc.t | 38 +++++++++--------- 3 files changed, 68 insertions(+), 74 deletions(-) diff --git a/src/Eval.cpp b/src/Eval.cpp index c1d644576..15dd67ca1 100644 --- a/src/Eval.cpp +++ b/src/Eval.cpp @@ -179,7 +179,7 @@ void Eval::compileExpression (const std::string& e) while (l.token (token, type)) { if (_debug) - context.debug ("evaluateInfixExpression token '" + token + "' " + Lexer::type_name (type)); + context.debug ("Lexer '" + token + "' " + Lexer::type_name (type)); _compiled.push_back (std::pair (token, type)); } @@ -257,13 +257,10 @@ void Eval::evaluatePostfixStack ( Variant right = values.back (); values.pop_back (); + Variant result = ! right; + values.push_back (result); if (_debug) - { - context.debug (format ("[{1}] eval pop '{2}'", values.size () + 1, (std::string) right)); - context.debug (format ("[{1}] eval operator '{2}'", values.size (), token->first)); - context.debug (format ("[{1}] eval result push '{2}'", values.size (), (bool) !right)); - } - values.push_back (! right); + context.debug (format ("Eval {1} ↓'{2}' → ↑'{3}'", token->first, (std::string) right, (std::string) result)); } else if (token->second == Lexer::typeOperator && token->first == "_neg_") @@ -276,23 +273,17 @@ void Eval::evaluatePostfixStack ( Variant result (0); result -= right; + values.push_back (result); if (_debug) - { - context.debug (format ("[{1}] eval pop '{2}'", values.size () + 1, (std::string) right)); - context.debug (format ("[{1}] eval operator '{2}'", values.size (), token->first)); - context.debug (format ("[{1}] eval result push '{2}'", values.size (), (std::string) result)); - } - values.push_back (result); + context.debug (format ("Eval {1} ↓'{2}' → ↑'{3}'", token->first, (std::string) right, (std::string) result)); } else if (token->second == Lexer::typeOperator && token->first == "_pos_") { - // NOP? + // The _pos_ operator is a NOP. if (_debug) - { - context.debug (format ("[{1}] eval operator '{2}'", values.size (), token->first)); - } + context.debug (format ("[{1}] eval op {2} NOP", values.size (), token->first)); } // Binary operators. @@ -307,43 +298,38 @@ void Eval::evaluatePostfixStack ( Variant left = values.back (); values.pop_back (); - if (_debug) - { - context.debug (format ("[{1}] eval pop '{2}'", values.size () + 2, (std::string) right)); - context.debug (format ("[{1}] eval pop '{2}'", values.size () + 1, (std::string) left)); - context.debug (format ("[{1}] eval operator '{2}'", values.size (), token->first)); - } - // Ordering these by anticipation frequency of use is a good idea. - if (token->first == "and") left = left && right; - else if (token->first == "or") left = left || right; - else if (token->first == "&&") left = left && right; - else if (token->first == "||") left = left || right; - else if (token->first == "<") left = left < right; - else if (token->first == "<=") left = left <= right; - else if (token->first == ">") left = left > right; - else if (token->first == ">=") left = left >= right; - else if (token->first == "==") left = left.operator== (right); - else if (token->first == "!==") left = left.operator!= (right); - else if (token->first == "=") left = left.operator_partial (right); - else if (token->first == "!=") left = left.operator_nopartial (right); - else if (token->first == "+") left += right; - else if (token->first == "-") left -= right; - else if (token->first == "*") left *= right; - else if (token->first == "/") left /= right; - else if (token->first == "^") left ^= right; - else if (token->first == "%") left %= right; - else if (token->first == "xor") left = left.operator_xor (right); - else if (token->first == "~") left = left.operator_match (right, contextTask); - else if (token->first == "!~") left = left.operator_nomatch (right, contextTask); - else if (token->first == "_hastag_") left = left.operator_hastag (right, contextTask); - else if (token->first == "_notag_") left = left.operator_notag (right, contextTask); + Variant result; + if (token->first == "and") result = left && right; + else if (token->first == "or") result = left || right; + else if (token->first == "&&") result = left && right; + else if (token->first == "||") result = left || right; + else if (token->first == "<") result = left < right; + else if (token->first == "<=") result = left <= right; + else if (token->first == ">") result = left > right; + else if (token->first == ">=") result = left >= right; + else if (token->first == "==") result = left.operator== (right); + else if (token->first == "!==") result = left.operator!= (right); + else if (token->first == "=") result = left.operator_partial (right); + else if (token->first == "!=") result = left.operator_nopartial (right); + else if (token->first == "+") result = left + right; + else if (token->first == "-") result = left - right; + else if (token->first == "*") result = left * right; + else if (token->first == "/") result = left / right; + else if (token->first == "^") result = left ^ right; + else if (token->first == "%") result = left % right; + else if (token->first == "xor") result = left.operator_xor (right); + else if (token->first == "~") result = left.operator_match (right, contextTask); + else if (token->first == "!~") result = left.operator_nomatch (right, contextTask); + else if (token->first == "_hastag_") result = left.operator_hastag (right, contextTask); + else if (token->first == "_notag_") result = left.operator_notag (right, contextTask); else throw format (STRING_EVAL_UNSUPPORTED, token->first); + values.push_back (result); + if (_debug) - context.debug (format ("[{1}] eval result push '{2}'", values.size (), (std::string) left)); - values.push_back (left); + context.debug (format ("Eval ↓'{1}' {2} ↓'{3}' → ↑'{4}'", (std::string) left, token->first, (std::string) right, (std::string) result)); } // Literals and identifiers. @@ -355,10 +341,14 @@ void Eval::evaluatePostfixStack ( case Lexer::typeNumber: case Lexer::typeHex: v.cast (Variant::type_integer); + if (_debug) + context.debug (format ("Eval literal number ↑'{1}'", (std::string) v)); break; case Lexer::typeDecimal: v.cast (Variant::type_real); + if (_debug) + context.debug (format ("Eval literal decimal ↑'{1}'", (std::string) v)); break; case Lexer::typeOperator: @@ -374,7 +364,7 @@ void Eval::evaluatePostfixStack ( if ((*source) (token->first, v)) { if (_debug) - context.debug (format ("[{1}] eval source '{2}' --> '{3}'", values.size (), token->first, (std::string) v)); + context.debug (format ("Eval identifier source '{1}' → ↑'{2}'", token->first, (std::string) v)); found = true; break; } @@ -385,27 +375,31 @@ void Eval::evaluatePostfixStack ( { v.cast (Variant::type_string); if (_debug) - context.debug (format ("[{1}] eval source failed '{2}'", values.size (), token->first)); + context.debug (format ("Eval identifier source failed '{1}'", token->first)); } } break; case Lexer::typeDate: v.cast (Variant::type_date); + if (_debug) + context.debug (format ("Eval literal date ↑'{1}'", (std::string) v)); break; case Lexer::typeDuration: v.cast (Variant::type_duration); + if (_debug) + context.debug (format ("Eval literal duration ↑'{1}'", (std::string) v)); break; // Nothing to do. case Lexer::typeString: default: + if (_debug) + context.debug (format ("Eval literal string ↑'{1}'", (std::string) v)); break; } - if (_debug) - context.debug (format ("[{1}] eval push '{2}'", values.size (), (std::string) v)); values.push_back (v); } } diff --git a/test/bug.calc.t b/test/bug.calc.t index 50587462c..2474a14af 100755 --- a/test/bug.calc.t +++ b/test/bug.calc.t @@ -36,8 +36,8 @@ my $output = qx{../src/calc --debug --noambiguous 15min}; unlike ($output, qr/token infix '15' Date/, "$ut: Misinterpretation: 15min -> 15"); unlike ($output, qr/token infix 'min' Identifier/, "$ut: Misinterpretation: 15min -> m"); unlike ($output, qr/Error: Unexpected stack size: 2/, "$ut: Unexpected stack size"); -like ($output, qr/\[0\] eval push 'PT15M'/, "$ut: 15min -> push PT15M"); -like ($output, qr/^PT15M$/ms, "$ut: 15min -> PT15M"); +like ($output, qr/Eval literal duration ↑'PT15M'/, "$ut: 15min -> push PT15M"); +like ($output, qr/^PT15M$/ms, "$ut: 15min -> PT15M"); exit 0; diff --git a/test/calc.t b/test/calc.t index 82911e884..7a0eb51fa 100755 --- a/test/calc.t +++ b/test/calc.t @@ -31,29 +31,29 @@ use Test::More tests => 19; # '15min' is seen as '15', 'min', not '15min' duration. my $output = qx{../src/calc --debug --noambiguous '12 * 3600 + 34 * 60 + 56'}; -like ($output, qr/eval push '12'/, 'Number 12'); -like ($output, qr/eval push '3600'/, 'Number 3600'); -like ($output, qr/eval push '34'/, 'Number 60'); -like ($output, qr/eval push '60'/, 'Number 60'); -like ($output, qr/eval push '56'/, 'Number 56'); -like ($output, qr/^45296$/ms, 'Result 45296'); -unlike ($output, qr/Error/, 'No errors'); +like ($output, qr/Eval literal number ↑'12'/, 'Number 12'); +like ($output, qr/Eval literal number ↑'3600'/, 'Number 3600'); +like ($output, qr/Eval literal number ↑'60'/, 'Number 60'); +like ($output, qr/Eval literal number ↑'60'/, 'Number 60'); +like ($output, qr/Eval literal number ↑'56'/, 'Number 56'); +like ($output, qr/^45296$/ms, 'Result 45296'); +unlike ($output, qr/Error/, 'No errors'); $output = qx{../src/calc --debug --noambiguous --postfix '12 3600 * 34 60 * 56 + +'}; -like ($output, qr/eval push '12'/, 'Number 12'); -like ($output, qr/eval push '3600'/, 'Number 3600'); -like ($output, qr/eval push '34'/, 'Number 60'); -like ($output, qr/eval push '60'/, 'Number 60'); -like ($output, qr/eval push '56'/, 'Number 56'); -like ($output, qr/^45296$/ms, 'Result 45296'); -unlike ($output, qr/Error/, 'No errors'); +like ($output, qr/Eval literal number ↑'12'/, 'Number 12'); +like ($output, qr/Eval literal number ↑'3600'/, 'Number 3600'); +like ($output, qr/Eval literal number ↑'60'/, 'Number 60'); +like ($output, qr/Eval literal number ↑'60'/, 'Number 60'); +like ($output, qr/Eval literal number ↑'56'/, 'Number 56'); +like ($output, qr/^45296$/ms, 'Result 45296'); +unlike ($output, qr/Error/, 'No errors'); $output = qx{../src/calc --debug --noambiguous '2--3'}; -like ($output, qr/eval push '2'/ms, 'Number 2'); -like ($output, qr/eval operator '-'/ms, 'Operator -'); -like ($output, qr/eval push '3'/ms, 'Number 3'); -like ($output, qr/^5$/ms, 'Result 5'); -unlike ($output, qr/Error/, 'No errors'); +like ($output, qr/Eval literal number ↑'2'/ms, 'Number 2'); +like ($output, qr/Eval _neg_ ↓'3' → ↑'-3'/ms, 'Operator -'); +like ($output, qr/Eval literal number ↑'2'/ms, 'Number 3'); +like ($output, qr/^5$/ms, 'Result 5'); +unlike ($output, qr/Error/, 'No errors'); exit 0;