Expression Refactor
- E9 now uses Arg object in place of Term. This means A3 and E9 are now using a common object.
This commit is contained in:
@@ -43,7 +43,6 @@ public:
|
|||||||
Arg& operator= (const Arg&);
|
Arg& operator= (const Arg&);
|
||||||
bool operator== (const Arg&) const;
|
bool operator== (const Arg&) const;
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
std::string _raw; // Raw input token, never modified
|
std::string _raw; // Raw input token, never modified
|
||||||
std::string _type; // Data type
|
std::string _type; // Data type
|
||||||
|
|||||||
293
src/E9.cpp
293
src/E9.cpp
@@ -25,21 +25,19 @@
|
|||||||
//
|
//
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#include <iostream> // TODO Remove.
|
#include <iostream>
|
||||||
#include <Context.h>
|
#include <Context.h>
|
||||||
#include <Date.h>
|
#include <Date.h>
|
||||||
#include <Duration.h>
|
#include <Duration.h>
|
||||||
#include <text.h>
|
#include <text.h>
|
||||||
#include <A3.h>
|
|
||||||
#include <E9.h>
|
#include <E9.h>
|
||||||
|
|
||||||
extern Context context;
|
extern Context context;
|
||||||
|
|
||||||
std::ostream& operator<< (std::ostream& out, const Term& term)
|
std::ostream& operator<< (std::ostream& out, const Arg& term)
|
||||||
{
|
{
|
||||||
out << term._raw << "/"
|
out << term._raw << "|"
|
||||||
<< term._value << "/"
|
<< term._type << "|"
|
||||||
<< term._type << "/"
|
|
||||||
<< term._category;
|
<< term._category;
|
||||||
|
|
||||||
return out;
|
return out;
|
||||||
@@ -51,7 +49,7 @@ E9::E9 (const A3& args)
|
|||||||
{
|
{
|
||||||
std::vector <Arg>::const_iterator arg;
|
std::vector <Arg>::const_iterator arg;
|
||||||
for (arg = args.begin (); arg != args.end (); ++arg)
|
for (arg = args.begin (); arg != args.end (); ++arg)
|
||||||
_terms.push_back (Term (*arg));
|
_terms.push_back (Arg (*arg));
|
||||||
|
|
||||||
_dateformat = context.config.get ("dateformat");
|
_dateformat = context.config.get ("dateformat");
|
||||||
}
|
}
|
||||||
@@ -67,11 +65,11 @@ bool E9::evalFilter (const Task& task)
|
|||||||
if (_terms.size () == 0)
|
if (_terms.size () == 0)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
std::vector <Term> value_stack;
|
std::vector <Arg> value_stack;
|
||||||
eval (task, value_stack);
|
eval (task, value_stack);
|
||||||
|
|
||||||
// Coerce result to Boolean.
|
// Coerce result to Boolean.
|
||||||
Term result = value_stack.back ();
|
Arg result = value_stack.back ();
|
||||||
value_stack.pop_back ();
|
value_stack.pop_back ();
|
||||||
return get_bool (coerce (result, "bool"));
|
return get_bool (coerce (result, "bool"));
|
||||||
}
|
}
|
||||||
@@ -82,24 +80,24 @@ std::string E9::evalExpression (const Task& task)
|
|||||||
if (_terms.size () == 0)
|
if (_terms.size () == 0)
|
||||||
return "";
|
return "";
|
||||||
|
|
||||||
std::vector <Term> value_stack;
|
std::vector <Arg> value_stack;
|
||||||
eval (task, value_stack);
|
eval (task, value_stack);
|
||||||
|
|
||||||
return value_stack.back ()._value;
|
return value_stack.back ()._raw;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
void E9::eval (const Task& task, std::vector <Term>& value_stack)
|
void E9::eval (const Task& task, std::vector <Arg>& value_stack)
|
||||||
{
|
{
|
||||||
// Case sensitivity is configurable.
|
// Case sensitivity is configurable.
|
||||||
bool case_sensitive = context.config.getBoolean ("search.case.sensitive");
|
bool case_sensitive = context.config.getBoolean ("search.case.sensitive");
|
||||||
|
|
||||||
std::vector <Term>::iterator arg;
|
std::vector <Arg>::iterator arg;
|
||||||
for (arg = _terms.begin (); arg != _terms.end (); ++arg)
|
for (arg = _terms.begin (); arg != _terms.end (); ++arg)
|
||||||
{
|
{
|
||||||
if (arg->_category == "op")
|
if (arg->_category == "op")
|
||||||
{
|
{
|
||||||
Term result;
|
Arg result;
|
||||||
|
|
||||||
// Unary operators.
|
// Unary operators.
|
||||||
if (arg->_raw == "!")
|
if (arg->_raw == "!")
|
||||||
@@ -107,15 +105,13 @@ void E9::eval (const Task& task, std::vector <Term>& value_stack)
|
|||||||
if (value_stack.size () < 1)
|
if (value_stack.size () < 1)
|
||||||
throw std::string ("There are no operands for the 'not' operator.");
|
throw std::string ("There are no operands for the 'not' operator.");
|
||||||
|
|
||||||
Term right = value_stack.back ();
|
Arg right = value_stack.back ();
|
||||||
value_stack.pop_back ();
|
value_stack.pop_back ();
|
||||||
|
|
||||||
if (right._category == "dom")
|
if (right._category == "dom")
|
||||||
{
|
{
|
||||||
if (context.config.getBoolean ("dom"))
|
if (context.config.getBoolean ("dom"))
|
||||||
right._value = context.dom.get (right._raw, task);
|
right._raw = context.dom.get (right._raw, task);
|
||||||
else
|
|
||||||
right._value = right._raw;
|
|
||||||
|
|
||||||
right._category = "string";
|
right._category = "string";
|
||||||
}
|
}
|
||||||
@@ -129,28 +125,24 @@ void E9::eval (const Task& task, std::vector <Term>& value_stack)
|
|||||||
if (value_stack.size () < 2)
|
if (value_stack.size () < 2)
|
||||||
throw std::string ("There are not enough operands for the '") + arg->_raw + "' operator.";
|
throw std::string ("There are not enough operands for the '") + arg->_raw + "' operator.";
|
||||||
|
|
||||||
Term right = value_stack.back ();
|
Arg right = value_stack.back ();
|
||||||
value_stack.pop_back ();
|
value_stack.pop_back ();
|
||||||
|
|
||||||
if (right._category == "dom")
|
if (right._category == "dom")
|
||||||
{
|
{
|
||||||
if (context.config.getBoolean ("dom"))
|
if (context.config.getBoolean ("dom"))
|
||||||
right._value = context.dom.get (right._raw, task);
|
right._raw = context.dom.get (right._raw, task);
|
||||||
else
|
|
||||||
right._value = right._raw;
|
|
||||||
|
|
||||||
right._category = "string";
|
right._category = "string";
|
||||||
}
|
}
|
||||||
|
|
||||||
Term left = value_stack.back ();
|
Arg left = value_stack.back ();
|
||||||
value_stack.pop_back ();
|
value_stack.pop_back ();
|
||||||
|
|
||||||
if (left._category == "dom")
|
if (left._category == "dom")
|
||||||
{
|
{
|
||||||
if (context.config.getBoolean ("dom"))
|
if (context.config.getBoolean ("dom"))
|
||||||
left._value = context.dom.get (left._raw, task);
|
left._raw = context.dom.get (left._raw, task);
|
||||||
else
|
|
||||||
left._value = left._raw;
|
|
||||||
|
|
||||||
left._category = "string";
|
left._category = "string";
|
||||||
}
|
}
|
||||||
@@ -183,11 +175,11 @@ void E9::eval (const Task& task, std::vector <Term>& value_stack)
|
|||||||
{
|
{
|
||||||
// Expand the value if possible.
|
// Expand the value if possible.
|
||||||
if (arg->_category == "dom")
|
if (arg->_category == "dom")
|
||||||
arg->_value = context.dom.get (arg->_raw, task);
|
arg->_raw = context.dom.get (arg->_raw, task);
|
||||||
else if (arg->_category == "date")
|
else if (arg->_category == "date")
|
||||||
arg->_value = Date (arg->_raw, _dateformat).toEpochString ();
|
arg->_raw = Date (arg->_raw, _dateformat).toEpochString ();
|
||||||
else if (arg->_category == "duration")
|
else if (arg->_category == "duration")
|
||||||
arg->_value = (std::string)Duration (arg->_raw);
|
arg->_raw = (std::string)Duration (arg->_raw);
|
||||||
|
|
||||||
//std::cout << "# E9::eval operand " << *arg << "\n";
|
//std::cout << "# E9::eval operand " << *arg << "\n";
|
||||||
value_stack.push_back (*arg);
|
value_stack.push_back (*arg);
|
||||||
@@ -200,7 +192,7 @@ void E9::eval (const Task& task, std::vector <Term>& value_stack)
|
|||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
bool E9::eval_match (Term& left, Term& right, bool case_sensitive)
|
bool E9::eval_match (Arg& left, Arg& right, bool case_sensitive)
|
||||||
{
|
{
|
||||||
if (right._category == "rx")
|
if (right._category == "rx")
|
||||||
{
|
{
|
||||||
@@ -208,17 +200,17 @@ bool E9::eval_match (Term& left, Term& right, bool case_sensitive)
|
|||||||
right = coerce (right, "string");
|
right = coerce (right, "string");
|
||||||
|
|
||||||
// Create a cached entry, if it does not already exist.
|
// Create a cached entry, if it does not already exist.
|
||||||
if (_regexes.find (right._value) == _regexes.end ())
|
if (_regexes.find (right._raw) == _regexes.end ())
|
||||||
_regexes[right._value] = RX (right._value, case_sensitive);
|
_regexes[right._raw] = RX (right._raw, case_sensitive);
|
||||||
|
|
||||||
if (_regexes[right._value].match (left._value))
|
if (_regexes[right._raw].match (left._raw))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
left = coerce (left, "string");
|
left = coerce (left, "string");
|
||||||
right = coerce (right, "string");
|
right = coerce (right, "string");
|
||||||
if (find (left._value, right._value, (bool) case_sensitive) != std::string::npos)
|
if (find (left._raw, right._raw, (bool) case_sensitive) != std::string::npos)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -226,25 +218,25 @@ bool E9::eval_match (Term& left, Term& right, bool case_sensitive)
|
|||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
void E9::operator_not (Term& result, Term& right)
|
void E9::operator_not (Arg& result, Arg& right)
|
||||||
{
|
{
|
||||||
// TODO This is not right.
|
// TODO This is not right.
|
||||||
result = Term (right._raw, coerce (right, "bool")._value, "bool", right._category);
|
result = Arg (right._raw, "bool", right._category);
|
||||||
|
|
||||||
// std::cout << "# not " << right << " --> " << result << "\n";
|
// std::cout << "# not " << right << " --> " << result << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
void E9::operator_and (Term& result, Term& left, Term& right)
|
void E9::operator_and (Arg& result, Arg& left, Arg& right)
|
||||||
{
|
{
|
||||||
// Assume failure.
|
// Assume failure.
|
||||||
result._raw = result._value = "false";
|
result._raw = "false";
|
||||||
result._category = "bool";
|
result._category = "bool";
|
||||||
|
|
||||||
if (coerce (left, "bool")._value == "true" &&
|
if (coerce (left, "bool")._raw == "true" &&
|
||||||
coerce (right, "bool")._value == "true" )
|
coerce (right, "bool")._raw == "true" )
|
||||||
{
|
{
|
||||||
result._raw = result._value = "true";
|
result._raw = "true";
|
||||||
result._category = "bool";
|
result._category = "bool";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -252,16 +244,16 @@ void E9::operator_and (Term& result, Term& left, Term& right)
|
|||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
void E9::operator_or (Term& result, Term& left, Term& right)
|
void E9::operator_or (Arg& result, Arg& left, Arg& right)
|
||||||
{
|
{
|
||||||
// Assume failure.
|
// Assume failure.
|
||||||
result._raw = result._value = "false";
|
result._raw = "false";
|
||||||
result._category = "bool";
|
result._category = "bool";
|
||||||
|
|
||||||
if (coerce (left, "bool")._value == "true" ||
|
if (coerce (left, "bool")._raw == "true" ||
|
||||||
coerce (right, "bool")._value == "true" )
|
coerce (right, "bool")._raw == "true" )
|
||||||
{
|
{
|
||||||
result._raw = result._value = "true";
|
result._raw = "true";
|
||||||
result._category = "bool";
|
result._category = "bool";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -269,19 +261,19 @@ void E9::operator_or (Term& result, Term& left, Term& right)
|
|||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
void E9::operator_xor (Term& result, Term& left, Term& right)
|
void E9::operator_xor (Arg& result, Arg& left, Arg& right)
|
||||||
{
|
{
|
||||||
// Assume failure.
|
// Assume failure.
|
||||||
result._raw = result._value = "false";
|
result._raw = "false";
|
||||||
result._category = "bool";
|
result._category = "bool";
|
||||||
|
|
||||||
bool bool_left = coerce (left, "bool")._value == "true";
|
bool bool_left = coerce (left, "bool")._raw == "true";
|
||||||
bool bool_right = coerce (right, "bool")._value == "true";
|
bool bool_right = coerce (right, "bool")._raw == "true";
|
||||||
|
|
||||||
if ((bool_left && !bool_right) ||
|
if ((bool_left && !bool_right) ||
|
||||||
(!bool_left && bool_right))
|
(!bool_left && bool_right))
|
||||||
{
|
{
|
||||||
result._raw = result._value = "true";
|
result._raw = "true";
|
||||||
result._category = "bool";
|
result._category = "bool";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -289,30 +281,30 @@ void E9::operator_xor (Term& result, Term& left, Term& right)
|
|||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
void E9::operator_lt (Term& result, Term& left, Term& right)
|
void E9::operator_lt (Arg& result, Arg& left, Arg& right)
|
||||||
{
|
{
|
||||||
if (left._raw == "priority")
|
if (left._raw == "priority")
|
||||||
{
|
{
|
||||||
if (left._value != "H" && right._value == "H") result._raw = result._value = "true";
|
if (left._raw != "H" && right._raw == "H") result._raw = "true";
|
||||||
else if (left._value == "L" && right._value == "M") result._raw = result._value = "true";
|
else if (left._raw == "L" && right._raw == "M") result._raw = "true";
|
||||||
else if (left._value == "" && right._value != "") result._raw = result._value = "true";
|
else if (left._raw == "" && right._raw != "") result._raw = "true";
|
||||||
else result._raw = result._value = "false";
|
else result._raw = "false";
|
||||||
}
|
}
|
||||||
else if (left._category == "date" ||
|
else if (left._category == "date" ||
|
||||||
right._category == "date")
|
right._category == "date")
|
||||||
{
|
{
|
||||||
Date left_date (left._value, _dateformat);
|
Date left_date (left._raw, _dateformat);
|
||||||
Date right_date (right._value, _dateformat);
|
Date right_date (right._raw, _dateformat);
|
||||||
|
|
||||||
result._raw = result._value = (left_date < right_date)
|
result._raw = result._raw = (left_date < right_date)
|
||||||
? "true"
|
? "true"
|
||||||
: "false";
|
: "false";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
result._raw = result._value = (left._value < right._value)
|
result._raw = result._raw = (left._raw < right._raw)
|
||||||
? "true"
|
? "true"
|
||||||
: "false";
|
: "false";
|
||||||
}
|
}
|
||||||
|
|
||||||
result._category = "bool";
|
result._category = "bool";
|
||||||
@@ -321,31 +313,31 @@ void E9::operator_lt (Term& result, Term& left, Term& right)
|
|||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
void E9::operator_lte (Term& result, Term& left, Term& right)
|
void E9::operator_lte (Arg& result, Arg& left, Arg& right)
|
||||||
{
|
{
|
||||||
if (left._raw == "priority")
|
if (left._raw == "priority")
|
||||||
{
|
{
|
||||||
if (left._value == right._value ) result._raw = result._value = "true";
|
if (left._raw == right._raw ) result._raw = "true";
|
||||||
else if ( right._value == "H") result._raw = result._value = "true";
|
else if ( right._raw == "H") result._raw = "true";
|
||||||
else if (left._value == "L" && right._value == "M") result._raw = result._value = "true";
|
else if (left._raw == "L" && right._raw == "M") result._raw = "true";
|
||||||
else if (left._value == "" ) result._raw = result._value = "true";
|
else if (left._raw == "" ) result._raw = "true";
|
||||||
else result._raw = result._value = "false";
|
else result._raw = "false";
|
||||||
}
|
}
|
||||||
else if (left._category == "date" ||
|
else if (left._category == "date" ||
|
||||||
right._category == "date")
|
right._category == "date")
|
||||||
{
|
{
|
||||||
Date left_date (left._value, _dateformat);
|
Date left_date (left._raw, _dateformat);
|
||||||
Date right_date (right._value, _dateformat);
|
Date right_date (right._raw, _dateformat);
|
||||||
|
|
||||||
result._raw = result._value = (left_date <= right_date)
|
result._raw = result._raw = (left_date <= right_date)
|
||||||
? "true"
|
? "true"
|
||||||
: "false";
|
: "false";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
result._raw = result._value = (left._value <= right._value)
|
result._raw = result._raw = (left._raw <= right._raw)
|
||||||
? "true"
|
? "true"
|
||||||
: "false";
|
: "false";
|
||||||
}
|
}
|
||||||
|
|
||||||
result._category = "bool";
|
result._category = "bool";
|
||||||
@@ -354,31 +346,31 @@ void E9::operator_lte (Term& result, Term& left, Term& right)
|
|||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
void E9::operator_gte (Term& result, Term& left, Term& right)
|
void E9::operator_gte (Arg& result, Arg& left, Arg& right)
|
||||||
{
|
{
|
||||||
if (left._raw == "priority")
|
if (left._raw == "priority")
|
||||||
{
|
{
|
||||||
if (left._value == right._value ) result._raw = result._value = "true";
|
if (left._raw == right._raw ) result._raw = "true";
|
||||||
else if (left._value == "H" ) result._raw = result._value = "true";
|
else if (left._raw == "H" ) result._raw = "true";
|
||||||
else if (left._value == "M" && right._value == "L") result._raw = result._value = "true";
|
else if (left._raw == "M" && right._raw == "L") result._raw = "true";
|
||||||
else if ( right._value == "" ) result._raw = result._value = "true";
|
else if ( right._raw == "" ) result._raw = "true";
|
||||||
else result._raw = result._value = "false";
|
else result._raw = "false";
|
||||||
}
|
}
|
||||||
else if (left._category == "date" ||
|
else if (left._category == "date" ||
|
||||||
right._category == "date")
|
right._category == "date")
|
||||||
{
|
{
|
||||||
Date left_date (left._value, _dateformat);
|
Date left_date (left._raw, _dateformat);
|
||||||
Date right_date (right._value, _dateformat);
|
Date right_date (right._raw, _dateformat);
|
||||||
|
|
||||||
result._raw = result._value = (left_date >= right_date)
|
result._raw = result._raw = (left_date >= right_date)
|
||||||
? "true"
|
? "true"
|
||||||
: "false";
|
: "false";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
result._raw = result._value = (left._value >= right._value)
|
result._raw = result._raw = (left._raw >= right._raw)
|
||||||
? "true"
|
? "true"
|
||||||
: "false";
|
: "false";
|
||||||
}
|
}
|
||||||
|
|
||||||
result._category = "bool";
|
result._category = "bool";
|
||||||
@@ -387,30 +379,30 @@ void E9::operator_gte (Term& result, Term& left, Term& right)
|
|||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
void E9::operator_gt (Term& result, Term& left, Term& right)
|
void E9::operator_gt (Arg& result, Arg& left, Arg& right)
|
||||||
{
|
{
|
||||||
if (left._raw == "priority")
|
if (left._raw == "priority")
|
||||||
{
|
{
|
||||||
if (left._value == "H" && right._value != "H") result._raw = result._value = "true";
|
if (left._raw == "H" && right._raw != "H") result._raw = "true";
|
||||||
else if (left._value == "M" && right._value == "L") result._raw = result._value = "true";
|
else if (left._raw == "M" && right._raw == "L") result._raw = "true";
|
||||||
else if (left._value != "" && right._value == "") result._raw = result._value = "true";
|
else if (left._raw != "" && right._raw == "") result._raw = "true";
|
||||||
else result._raw = result._value = "false";
|
else result._raw = "false";
|
||||||
}
|
}
|
||||||
else if (left._category == "date" ||
|
else if (left._category == "date" ||
|
||||||
right._category == "date")
|
right._category == "date")
|
||||||
{
|
{
|
||||||
Date left_date (left._value, _dateformat);
|
Date left_date (left._raw, _dateformat);
|
||||||
Date right_date (right._value, _dateformat);
|
Date right_date (right._raw, _dateformat);
|
||||||
|
|
||||||
result._raw = result._value = (left_date > right_date)
|
result._raw = result._raw = (left_date > right_date)
|
||||||
? "true"
|
? "true"
|
||||||
: "false";
|
: "false";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
result._raw = result._value = (left._value > right._value)
|
result._raw = result._raw = (left._raw > right._raw)
|
||||||
? "true"
|
? "true"
|
||||||
: "false";
|
: "false";
|
||||||
}
|
}
|
||||||
|
|
||||||
result._category = "bool";
|
result._category = "bool";
|
||||||
@@ -420,15 +412,15 @@ void E9::operator_gt (Term& result, Term& left, Term& right)
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
void E9::operator_inequal (
|
void E9::operator_inequal (
|
||||||
Term& result,
|
Arg& result,
|
||||||
Term& left,
|
Arg& left,
|
||||||
Term& right,
|
Arg& right,
|
||||||
bool case_sensitive)
|
bool case_sensitive)
|
||||||
{
|
{
|
||||||
operator_equal (result, left, right, case_sensitive);
|
operator_equal (result, left, right, case_sensitive);
|
||||||
result._raw = result._value = result._raw == "false"
|
result._raw = result._raw == "false"
|
||||||
? "true"
|
? "true"
|
||||||
: "false";
|
: "false";
|
||||||
|
|
||||||
// std::cout << "# " << left << " != " << right << " --> " << result << "\n";
|
// std::cout << "# " << left << " != " << right << " --> " << result << "\n";
|
||||||
}
|
}
|
||||||
@@ -442,13 +434,13 @@ void E9::operator_inequal (
|
|||||||
// else
|
// else
|
||||||
// result = (left == right);
|
// result = (left == right);
|
||||||
void E9::operator_equal (
|
void E9::operator_equal (
|
||||||
Term& result,
|
Arg& result,
|
||||||
Term& left,
|
Arg& left,
|
||||||
Term& right,
|
Arg& right,
|
||||||
bool case_sensitive)
|
bool case_sensitive)
|
||||||
{
|
{
|
||||||
// Assume failure.
|
// Assume failure.
|
||||||
result._raw = result._value = "false";
|
result._raw = "false";
|
||||||
result._category = "bool";
|
result._category = "bool";
|
||||||
|
|
||||||
// 'project' and 'recur' attributes are matched leftmost.
|
// 'project' and 'recur' attributes are matched leftmost.
|
||||||
@@ -457,12 +449,12 @@ void E9::operator_equal (
|
|||||||
coerce (left, "string");
|
coerce (left, "string");
|
||||||
coerce (right, "string");
|
coerce (right, "string");
|
||||||
|
|
||||||
if (right._value.length () <= left._value.length () &&
|
if (right._raw.length () <= left._raw.length () &&
|
||||||
compare (right._value,
|
compare (right._raw,
|
||||||
left._value.substr (0, right._value.length ()),
|
left._raw.substr (0, right._raw.length ()),
|
||||||
(bool) case_sensitive))
|
(bool) case_sensitive))
|
||||||
{
|
{
|
||||||
result._raw = result._value = "true";
|
result._raw = "true";
|
||||||
result._category = "bool";
|
result._category = "bool";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -471,23 +463,23 @@ void E9::operator_equal (
|
|||||||
else if (left._category == "date" ||
|
else if (left._category == "date" ||
|
||||||
right._category == "date")
|
right._category == "date")
|
||||||
{
|
{
|
||||||
Date left_date (left._value, _dateformat);
|
Date left_date (left._raw, _dateformat);
|
||||||
Date right_date (right._value, _dateformat);
|
Date right_date (right._raw, _dateformat);
|
||||||
|
|
||||||
result._raw = result._value = (left_date == right_date)
|
result._raw = (left_date == right_date)
|
||||||
? "true"
|
? "true"
|
||||||
: "false";
|
: "false";
|
||||||
}
|
}
|
||||||
// Regular equality matching.
|
// Regular equality matching.
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
result._raw = result._value = left._value == right._value
|
result._raw = left._raw == right._raw
|
||||||
? "true"
|
? "true"
|
||||||
: "false";
|
: "false";
|
||||||
|
|
||||||
if (left._value == right._value)
|
if (left._raw == right._raw)
|
||||||
{
|
{
|
||||||
result._raw = result._value = "true";
|
result._raw = "true";
|
||||||
result._category = "bool";
|
result._category = "bool";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -497,16 +489,16 @@ void E9::operator_equal (
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
void E9::operator_match (
|
void E9::operator_match (
|
||||||
Term& result,
|
Arg& result,
|
||||||
Term& left,
|
Arg& left,
|
||||||
Term& right,
|
Arg& right,
|
||||||
bool case_sensitive)
|
bool case_sensitive)
|
||||||
{
|
{
|
||||||
result._category = "bool";
|
result._category = "bool";
|
||||||
|
|
||||||
result._raw = result._value = eval_match (left, right, case_sensitive)
|
result._raw = eval_match (left, right, case_sensitive)
|
||||||
? "true"
|
? "true"
|
||||||
: "false";
|
: "false";
|
||||||
|
|
||||||
// std::cout << "# " << left << " ~ " << right << " --> " << result << "\n";
|
// std::cout << "# " << left << " ~ " << right << " --> " << result << "\n";
|
||||||
}
|
}
|
||||||
@@ -523,60 +515,59 @@ void E9::operator_match (
|
|||||||
// // TODO check further.
|
// // TODO check further.
|
||||||
// }
|
// }
|
||||||
void E9::operator_nomatch (
|
void E9::operator_nomatch (
|
||||||
Term& result,
|
Arg& result,
|
||||||
Term& left,
|
Arg& left,
|
||||||
Term& right,
|
Arg& right,
|
||||||
bool case_sensitive)
|
bool case_sensitive)
|
||||||
{
|
{
|
||||||
result._category = "bool";
|
result._category = "bool";
|
||||||
|
|
||||||
result._raw = result._value = eval_match (left, right, case_sensitive)
|
result._raw = eval_match (left, right, case_sensitive)
|
||||||
? "false"
|
? "false"
|
||||||
: "true";
|
: "true";
|
||||||
|
|
||||||
// std::cout << "# " << left << " !~ " << right << " --> " << result << "\n";
|
// std::cout << "# " << left << " !~ " << right << " --> " << result << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
void E9::operator_multiply (Term& result, Term& left, Term& right)
|
void E9::operator_multiply (Arg& result, Arg& left, Arg& right)
|
||||||
{
|
{
|
||||||
// std::cout << "# " << left << " * " << right << " --> " << result << "\n";
|
// std::cout << "# " << left << " * " << right << " --> " << result << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
void E9::operator_divide (Term& result, Term& left, Term& right)
|
void E9::operator_divide (Arg& result, Arg& left, Arg& right)
|
||||||
{
|
{
|
||||||
// std::cout << "# " << left << " / " << right << " --> " << result << "\n";
|
// std::cout << "# " << left << " / " << right << " --> " << result << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
void E9::operator_add (Term& result, Term& left, Term& right)
|
void E9::operator_add (Arg& result, Arg& left, Arg& right)
|
||||||
{
|
{
|
||||||
// std::cout << "# " << left << " + " << right << " --> " << result << "\n";
|
// std::cout << "# " << left << " + " << right << " --> " << result << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
void E9::operator_subtract (Term& result, Term& left, Term& right)
|
void E9::operator_subtract (Arg& result, Arg& left, Arg& right)
|
||||||
{
|
{
|
||||||
// std::cout << "# " << left << " - " << right << " --> " << result << "\n";
|
// std::cout << "# " << left << " - " << right << " --> " << result << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
const Term E9::coerce (const Term& input, const std::string& type)
|
const Arg E9::coerce (const Arg& input, const std::string& type)
|
||||||
{
|
{
|
||||||
Term result;
|
Arg result;
|
||||||
|
|
||||||
if (type == "bool")
|
if (type == "bool")
|
||||||
{
|
{
|
||||||
result._category = "bool";
|
result._category = "bool";
|
||||||
result._value = get_bool (input) ? "true" : "false";
|
result._raw = get_bool (input) ? "true" : "false";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type == "string")
|
if (type == "string")
|
||||||
{
|
{
|
||||||
// TODO Convert date?
|
// TODO Convert date?
|
||||||
result._raw = input._raw;
|
result._raw = input._raw;
|
||||||
result._value = input._value;
|
|
||||||
result._category = "string";
|
result._category = "string";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -587,9 +578,9 @@ const Term E9::coerce (const Term& input, const std::string& type)
|
|||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
bool E9::get_bool (const Term& input)
|
bool E9::get_bool (const Arg& input)
|
||||||
{
|
{
|
||||||
std::string value = lowerCase (input._value);
|
std::string value = lowerCase (input._raw);
|
||||||
if (value == "true" ||
|
if (value == "true" ||
|
||||||
value == "t" ||
|
value == "t" ||
|
||||||
value == "1" ||
|
value == "1" ||
|
||||||
|
|||||||
109
src/E9.h
109
src/E9.h
@@ -33,73 +33,6 @@
|
|||||||
#include <Task.h>
|
#include <Task.h>
|
||||||
#include <RX.h>
|
#include <RX.h>
|
||||||
|
|
||||||
class Term
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
Term ()
|
|
||||||
: _raw ("")
|
|
||||||
, _value ("")
|
|
||||||
, _type ("")
|
|
||||||
, _category ("")
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
Term (const Arg& arg)
|
|
||||||
: _raw (arg._raw)
|
|
||||||
, _value (arg._raw)
|
|
||||||
, _type ("string")
|
|
||||||
, _category (arg._category)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
Term (
|
|
||||||
const std::string& raw,
|
|
||||||
const std::string& value,
|
|
||||||
const std::string& type,
|
|
||||||
const std::string& category)
|
|
||||||
: _raw (raw)
|
|
||||||
, _value (value)
|
|
||||||
, _type (type)
|
|
||||||
, _category (category)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
Term (const Term& other)
|
|
||||||
{
|
|
||||||
_raw = other._raw;
|
|
||||||
_value = other._value;
|
|
||||||
_type = other._type;
|
|
||||||
_category = other._category;
|
|
||||||
}
|
|
||||||
|
|
||||||
Term& operator= (const Term& other)
|
|
||||||
{
|
|
||||||
if (this != &other)
|
|
||||||
{
|
|
||||||
_raw = other._raw;
|
|
||||||
_value = other._value;
|
|
||||||
_type = other._type;
|
|
||||||
_category = other._category;
|
|
||||||
}
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator== (const Term& other) const
|
|
||||||
{
|
|
||||||
return _raw == other._raw &&
|
|
||||||
_value == other._value &&
|
|
||||||
_type == other._type &&
|
|
||||||
_category == other._category;
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
std::string _raw; // Raw input token, never modified
|
|
||||||
std::string _value; // Evaluated raw token, sometimes identical
|
|
||||||
std::string _type; // Inferred type
|
|
||||||
std::string _category; // Categorized argument
|
|
||||||
};
|
|
||||||
|
|
||||||
class E9
|
class E9
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -110,34 +43,34 @@ public:
|
|||||||
std::string evalExpression (const Task&);
|
std::string evalExpression (const Task&);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void eval (const Task&, std::vector <Term>&);
|
void eval (const Task&, std::vector <Arg>&);
|
||||||
bool eval_match (Term&, Term&, bool);
|
bool eval_match (Arg&, Arg&, bool);
|
||||||
|
|
||||||
// Unary.
|
// Unary.
|
||||||
void operator_not (Term&, Term&);
|
void operator_not (Arg&, Arg&);
|
||||||
|
|
||||||
// Binary.
|
// Binary.
|
||||||
void operator_and (Term&, Term&, Term&);
|
void operator_and (Arg&, Arg&, Arg&);
|
||||||
void operator_or (Term&, Term&, Term&);
|
void operator_or (Arg&, Arg&, Arg&);
|
||||||
void operator_xor (Term&, Term&, Term&);
|
void operator_xor (Arg&, Arg&, Arg&);
|
||||||
void operator_lt (Term&, Term&, Term&);
|
void operator_lt (Arg&, Arg&, Arg&);
|
||||||
void operator_lte (Term&, Term&, Term&);
|
void operator_lte (Arg&, Arg&, Arg&);
|
||||||
void operator_gte (Term&, Term&, Term&);
|
void operator_gte (Arg&, Arg&, Arg&);
|
||||||
void operator_gt (Term&, Term&, Term&);
|
void operator_gt (Arg&, Arg&, Arg&);
|
||||||
void operator_inequal (Term&, Term&, Term&, bool);
|
void operator_inequal (Arg&, Arg&, Arg&, bool);
|
||||||
void operator_equal (Term&, Term&, Term&, bool);
|
void operator_equal (Arg&, Arg&, Arg&, bool);
|
||||||
void operator_match (Term&, Term&, Term&, bool);
|
void operator_match (Arg&, Arg&, Arg&, bool);
|
||||||
void operator_nomatch (Term&, Term&, Term&, bool);
|
void operator_nomatch (Arg&, Arg&, Arg&, bool);
|
||||||
void operator_multiply (Term&, Term&, Term&);
|
void operator_multiply (Arg&, Arg&, Arg&);
|
||||||
void operator_divide (Term&, Term&, Term&);
|
void operator_divide (Arg&, Arg&, Arg&);
|
||||||
void operator_add (Term&, Term&, Term&);
|
void operator_add (Arg&, Arg&, Arg&);
|
||||||
void operator_subtract (Term&, Term&, Term&);
|
void operator_subtract (Arg&, Arg&, Arg&);
|
||||||
|
|
||||||
const Term coerce (const Term&, const std::string&);
|
const Arg coerce (const Arg&, const std::string&);
|
||||||
bool get_bool (const Term&);
|
bool get_bool (const Arg&);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector <Term> _terms;
|
std::vector <Arg> _terms;
|
||||||
std::map <std::string, RX> _regexes;
|
std::map <std::string, RX> _regexes;
|
||||||
std::string _dateformat;
|
std::string _dateformat;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -45,7 +45,6 @@ qx{../src/task rc:bug.rc add one +ordinary};
|
|||||||
qx{../src/task rc:bug.rc add two +\@strange};
|
qx{../src/task rc:bug.rc add two +\@strange};
|
||||||
|
|
||||||
my $output = qx{../src/task rc:bug.rc long +ordinary};
|
my $output = qx{../src/task rc:bug.rc long +ordinary};
|
||||||
diag ($output);
|
|
||||||
like ($output, qr/one/, '+ordinary explicitly included'); # 2
|
like ($output, qr/one/, '+ordinary explicitly included'); # 2
|
||||||
unlike ($output, qr/two/, '@strange implicitly excluded');
|
unlike ($output, qr/two/, '@strange implicitly excluded');
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user