Expressions

- Implemented expression escalation: when matching against description,
  escalate to include annotations on failure.  Needs adjustment to
  DOM eval before it will work.
This commit is contained in:
Paul Beckingham 2011-08-31 23:36:16 -04:00
parent dfe72d7de7
commit 5f4571b0d0
2 changed files with 68 additions and 23 deletions

View file

@ -137,8 +137,8 @@ void E9::eval (const Task& task, std::vector <Arg>& value_stack)
else if (arg->_raw == ">") operator_gt (result, left, right); else if (arg->_raw == ">") operator_gt (result, left, right);
else if (arg->_raw == "!=") operator_inequal (result, left, right, case_sensitive); else if (arg->_raw == "!=") operator_inequal (result, left, right, case_sensitive);
else if (arg->_raw == "=") operator_equal (result, left, right, case_sensitive); else if (arg->_raw == "=") operator_equal (result, left, right, case_sensitive);
else if (arg->_raw == "~") operator_match (result, left, right, case_sensitive); else if (arg->_raw == "~") operator_match (result, left, right, case_sensitive, task);
else if (arg->_raw == "!~") operator_nomatch (result, left, right, case_sensitive); else if (arg->_raw == "!~") operator_nomatch (result, left, right, case_sensitive, task);
else if (arg->_raw == "*") operator_multiply (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_divide (result, left, right);
else if (arg->_raw == "+") operator_add (result, left, right); else if (arg->_raw == "+") operator_add (result, left, right);
@ -498,41 +498,86 @@ void E9::operator_equal (
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// Match may occur in description or any annotation. Short circuits.
void E9::operator_match ( void E9::operator_match (
Arg& result, Arg& result,
Arg& left, Arg& left,
Arg& right, Arg& right,
bool case_sensitive) bool case_sensitive,
const Task& task)
{ {
result._type = Arg::type_bool; result._type = Arg::type_bool;
result._value = eval_match (left, right, case_sensitive)
? "true" // TODO The problem is that description/dom -> <description>/string and we lose the original value.
: "false";
if (eval_match (left, right, case_sensitive))
{
// std::cout << "# operator_match description match\n";
result._value = "true";
}
else if (left._raw == "description")
{
// std::cout << "# operator_match escalation\n";
std::map <std::string, std::string> annotations;
task.getAnnotations (annotations);
std::map <std::string, std::string>::iterator a;
for (a = annotations.begin (); a != annotations.end (); ++a)
{
// Clone 'right', override _value.
Arg alternate (right);
alternate._value = a->second;
if (eval_match (left, alternate, case_sensitive))
{
// std::cout << "# operator_match annotation match\n";
result._value = "true";
break;
}
}
}
else
result._value = "false";
// std::cout << "# " << left << " <operator_match> " << right << " --> " << result << "\n"; // std::cout << "# " << left << " <operator_match> " << right << " --> " << result << "\n";
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// bool case_sensitive = context.config.getBoolean ("search.case.sensitive"); // Match may not occur in description or any annotation. Short circuits.
// bool result = !eval_match (left, right, case_sensitive);
//
// // Matches against description are really against either description,
// // annotations or project.
// // Short-circuit if match already failed.
// if (result && left._raw == "description")
// {
// // TODO check further.
// }
void E9::operator_nomatch ( void E9::operator_nomatch (
Arg& result, Arg& result,
Arg& left, Arg& left,
Arg& right, Arg& right,
bool case_sensitive) bool case_sensitive,
const Task& task)
{ {
result._type = Arg::type_bool; result._type = Arg::type_bool;
result._value = eval_match (left, right, case_sensitive)
? "false" if (eval_match (left, right, case_sensitive))
: "true"; {
result._value = "false";
}
else if (left._raw == "description")
{
std::map <std::string, std::string> annotations;
task.getAnnotations (annotations);
std::map <std::string, std::string>::iterator a;
for (a = annotations.begin (); a != annotations.end (); ++a)
{
// Clone 'right', override _value.
Arg alternate (right);
alternate._value = a->second;
if (eval_match (left, alternate, case_sensitive))
{
result._value = "false";
break;
}
}
}
else
result._value = "true";
// std::cout << "# " << left << " <operator_nomatch> " << right << " --> " << result << "\n"; // std::cout << "# " << left << " <operator_nomatch> " << right << " --> " << result << "\n";
} }

View file

@ -59,8 +59,8 @@ private:
void operator_gt (Arg&, Arg&, Arg&); void operator_gt (Arg&, Arg&, Arg&);
void operator_inequal (Arg&, Arg&, Arg&, bool); void operator_inequal (Arg&, Arg&, Arg&, bool);
void operator_equal (Arg&, Arg&, Arg&, bool); void operator_equal (Arg&, Arg&, Arg&, bool);
void operator_match (Arg&, Arg&, Arg&, bool); void operator_match (Arg&, Arg&, Arg&, bool, const Task&);
void operator_nomatch (Arg&, Arg&, Arg&, bool); void operator_nomatch (Arg&, Arg&, Arg&, bool, const Task&);
void operator_multiply (Arg&, Arg&, Arg&); void operator_multiply (Arg&, Arg&, Arg&);
void operator_divide (Arg&, Arg&, Arg&); void operator_divide (Arg&, Arg&, Arg&);
void operator_add (Arg&, Arg&, Arg&); void operator_add (Arg&, Arg&, Arg&);