diff --git a/src/A3.h b/src/A3.h index 76221a13b..36224cd30 100644 --- a/src/A3.h +++ b/src/A3.h @@ -37,6 +37,12 @@ class Arg { public: + Arg () + : _raw ("") + , _category ("") + { + } + Arg ( const std::string& raw, const std::string& category) diff --git a/src/E9.cpp b/src/E9.cpp index c4338b551..1d813bd63 100644 --- a/src/E9.cpp +++ b/src/E9.cpp @@ -27,6 +27,7 @@ #include // TODO Remove. #include +#include #include extern Context context; @@ -49,15 +50,277 @@ bool E9::evalFilter (const Task& task) if (_args.size () == 0) return true; + std::vector value_stack; + eval (task, value_stack); + // TODO Coerce result to Boolean. return true; } //////////////////////////////////////////////////////////////////////////////// -std::string evalExpression (const Task& task) +std::string E9::evalExpression (const Task& task) { + if (_args.size () == 0) + return ""; - return ""; + std::vector value_stack; + eval (task, value_stack); + + return value_stack.back ()._raw; +} + +//////////////////////////////////////////////////////////////////////////////// +void E9::eval (const Task& task, std::vector & value_stack) +{ + // Case sensitivity is configurable. + bool case_sensitive = context.config.getBoolean ("search.case.sensitive"); + + std::vector ::iterator arg; + for (arg = _args.begin (); arg != _args.end (); ++arg) + { + if (arg->_category == "op") + { + Arg result; + + // Unary operators. + if (arg->_raw == "!") + { + Arg right = value_stack.back (); + value_stack.pop_back (); + operator_not (result, right); + } + + // Binary operators. + else + { + Arg right = value_stack.back (); + value_stack.pop_back (); + Arg left = value_stack.back (); + value_stack.pop_back (); + + if (arg->_raw == "and") operator_and (result, left, right); + else if (arg->_raw == "or") operator_or (result, left, right); + else if (arg->_raw == "xor") operator_xor (result, left, right); + else if (arg->_raw == "<") operator_lt (result, left, right); + else if (arg->_raw == "<=") operator_lte (result, left, right); + else if (arg->_raw == ">=") operator_gte (result, left, right); + else if (arg->_raw == ">") operator_gt (result, left, right); + else if (arg->_raw == "!=") operator_inequal (result, left, right); + else if (arg->_raw == "=") operator_equal (result, left, right); + else if (arg->_raw == "~") operator_match (result, left, right); + else if (arg->_raw == "!~") operator_nomatch (result, left, right); + else if (arg->_raw == "*") operator_multiply (result, left, right); + else if (arg->_raw == "/") operator_divide (result, left, right); + else if (arg->_raw == "+") operator_add (result, left, right); + else if (arg->_raw == "-") operator_subtract (result, left, right); + else + throw std::string ("Unsupported operator '") + arg->_raw + "'."; + } + + // Store the result. + value_stack.push_back (result); + } + + // Operand. + else + { + value_stack.push_back (*arg); + } + } + + // Check for stack remnants. + if (value_stack.size () != 1) + throw std::string ("Error: Expression::eval found extra items on the stack."); +} + +//////////////////////////////////////////////////////////////////////////////// +void E9::operator_not (Arg& result, Arg& left) +{ + + std::cout << "# not " << left._raw << "/" << left._category + << " --> " + << result._raw << "/" << result._category + << "\n"; +} + +//////////////////////////////////////////////////////////////////////////////// +void E9::operator_and (Arg& result, Arg& left, Arg& right) +{ + + std::cout << "# " << left._raw << "/" << left._category + << " and " + << right._raw << "/" << right._category + << " --> " + << result._raw << "/" << result._category + << "\n"; +} + +//////////////////////////////////////////////////////////////////////////////// +void E9::operator_or (Arg& result, Arg& left, Arg& right) +{ + + std::cout << "# " << left._raw << "/" << left._category + << " or " + << right._raw << "/" << right._category + << " --> " + << result._raw << "/" << result._category + << "\n"; +} + +//////////////////////////////////////////////////////////////////////////////// +void E9::operator_xor (Arg& result, Arg& left, Arg& right) +{ + + std::cout << "# " << left._raw << "/" << left._category + << " xor " + << right._raw << "/" << right._category + << " --> " + << result._raw << "/" << result._category + << "\n"; +} + +//////////////////////////////////////////////////////////////////////////////// +void E9::operator_lt (Arg& result, Arg& left, Arg& right) +{ + + std::cout << "# " << left._raw << "/" << left._category + << " < " + << right._raw << "/" << right._category + << " --> " + << result._raw << "/" << result._category + << "\n"; +} + +//////////////////////////////////////////////////////////////////////////////// +void E9::operator_lte (Arg& result, Arg& left, Arg& right) +{ + + std::cout << "# " << left._raw << "/" << left._category + << " <= " + << right._raw << "/" << right._category + << " --> " + << result._raw << "/" << result._category + << "\n"; +} + +//////////////////////////////////////////////////////////////////////////////// +void E9::operator_gte (Arg& result, Arg& left, Arg& right) +{ + + std::cout << "# " << left._raw << "/" << left._category + << " >= " + << right._raw << "/" << right._category + << " --> " + << result._raw << "/" << result._category + << "\n"; +} + +//////////////////////////////////////////////////////////////////////////////// +void E9::operator_gt (Arg& result, Arg& left, Arg& right) +{ + + std::cout << "# " << left._raw << "/" << left._category + << " > " + << right._raw << "/" << right._category + << " --> " + << result._raw << "/" << result._category + << "\n"; +} + +//////////////////////////////////////////////////////////////////////////////// +void E9::operator_inequal (Arg& result, Arg& left, Arg& right) +{ + + std::cout << "# " << left._raw << "/" << left._category + << " != " + << right._raw << "/" << right._category + << " --> " + << result._raw << "/" << result._category + << "\n"; +} + +//////////////////////////////////////////////////////////////////////////////// +void E9::operator_equal (Arg& result, Arg& left, Arg& right) +{ + + std::cout << "# " << left._raw << "/" << left._category + << " = " + << right._raw << "/" << right._category + << " --> " + << result._raw << "/" << result._category + << "\n"; +} + +//////////////////////////////////////////////////////////////////////////////// +void E9::operator_match (Arg& result, Arg& left, Arg& right) +{ + + std::cout << "# " << left._raw << "/" << left._category + << " ~ " + << right._raw << "/" << right._category + << " --> " + << result._raw << "/" << result._category + << "\n"; +} + +//////////////////////////////////////////////////////////////////////////////// +void E9::operator_nomatch (Arg& result, Arg& left, Arg& right) +{ + + std::cout << "# " << left._raw << "/" << left._category + << " !~ " + << right._raw << "/" << right._category + << " --> " + << result._raw << "/" << result._category + << "\n"; +} + +//////////////////////////////////////////////////////////////////////////////// +void E9::operator_multiply (Arg& result, Arg& left, Arg& right) +{ + + std::cout << "# " << left._raw << "/" << left._category + << " * " + << right._raw << "/" << right._category + << " --> " + << result._raw << "/" << result._category + << "\n"; +} + +//////////////////////////////////////////////////////////////////////////////// +void E9::operator_divide (Arg& result, Arg& left, Arg& right) +{ + + std::cout << "# " << left._raw << "/" << left._category + << " / " + << right._raw << "/" << right._category + << " --> " + << result._raw << "/" << result._category + << "\n"; +} + +//////////////////////////////////////////////////////////////////////////////// +void E9::operator_add (Arg& result, Arg& left, Arg& right) +{ + + std::cout << "# " << left._raw << "/" << left._category + << " + " + << right._raw << "/" << right._category + << " --> " + << result._raw << "/" << result._category + << "\n"; +} + +//////////////////////////////////////////////////////////////////////////////// +void E9::operator_subtract (Arg& result, Arg& left, Arg& right) +{ + + std::cout << "# " << left._raw << "/" << left._category + << " - " + << right._raw << "/" << right._category + << " --> " + << result._raw << "/" << result._category + << "\n"; } //////////////////////////////////////////////////////////////////////////////// diff --git a/src/E9.h b/src/E9.h index 18b0262c1..96d6577ee 100644 --- a/src/E9.h +++ b/src/E9.h @@ -42,6 +42,29 @@ public: bool evalFilter (const Task&); std::string evalExpression (const Task&); +private: + void eval (const Task&, std::vector &); + + // Unary. + void operator_not (Arg&, Arg&); + + // Binary. + void operator_and (Arg&, Arg&, Arg&); + void operator_or (Arg&, Arg&, Arg&); + void operator_xor (Arg&, Arg&, Arg&); + void operator_lt (Arg&, Arg&, Arg&); + void operator_lte (Arg&, Arg&, Arg&); + void operator_gte (Arg&, Arg&, Arg&); + void operator_gt (Arg&, Arg&, Arg&); + void operator_inequal (Arg&, Arg&, Arg&); + void operator_equal (Arg&, Arg&, Arg&); + void operator_match (Arg&, Arg&, Arg&); + void operator_nomatch (Arg&, Arg&, Arg&); + void operator_multiply (Arg&, Arg&, Arg&); + void operator_divide (Arg&, Arg&, Arg&); + void operator_add (Arg&, Arg&, Arg&); + void operator_subtract (Arg&, Arg&, Arg&); + private: A3 _args; std::map _regexes; diff --git a/src/commands/CmdShow.cpp b/src/commands/CmdShow.cpp index 8eecf0f5f..0e9d5b44c 100644 --- a/src/commands/CmdShow.cpp +++ b/src/commands/CmdShow.cpp @@ -269,16 +269,6 @@ int CmdShow::execute (std::string& output) if (context.args.size () == 2) section = context.args[1]; */ -/* - Arguments args = context.args.extract_read_only_filter (); - std::vector >::iterator arg; - for (arg = args.begin (); arg != args.end (); ++arg) - { - if (arg->second == "string") - { - } - } -*/ if (section == "all") section = ""; diff --git a/src/commands/Command.cpp b/src/commands/Command.cpp index b755c7428..f2d4f4c07 100644 --- a/src/commands/Command.cpp +++ b/src/commands/Command.cpp @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -82,8 +83,8 @@ #include #include #include -#include +#include #include #include #include @@ -268,10 +269,8 @@ void Command::filter (std::vector & input, std::vector & output) { Timer timer ("Command::filter"); -/**/ A3 filt = context.a3.extract_filter (); filt.dump ("extract_filter"); -/**/ Arguments f; if (read_only ()) @@ -282,6 +281,7 @@ void Command::filter (std::vector & input, std::vector & output) if (f.size ()) { Expression e (f); + E9 expr (filt); std::vector ::iterator task; for (task = input.begin (); task != input.end (); ++task) @@ -298,14 +298,9 @@ void Command::filter (std::vector & output) { Timer timer ("Command::filter"); -/**/ A3 filt = context.a3.extract_filter (); filt.dump ("extract_filter"); - A3 mods = context.a3.extract_modifications (); - mods.dump ("extract_modifications"); -/**/ - Arguments f; if (read_only ()) f = context.args.extract_read_only_filter (); @@ -316,6 +311,7 @@ void Command::filter (std::vector & output) { const std::vector & pending = context.tdb2.pending.get_tasks (); Expression e (f); + E9 expr (filt); output.clear (); std::vector ::const_iterator task;