mirror of
https://github.com/GothenburgBitFactory/taskwarrior.git
synced 2025-06-26 10:54:26 +02:00
Bug
- Fixed bug in named entity lookup. - Removed obsolete failing test.
This commit is contained in:
parent
62eafb6639
commit
05c90b1779
2 changed files with 40 additions and 9 deletions
21
src/Eval.cpp
21
src/Eval.cpp
|
@ -28,6 +28,7 @@
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <Eval.h>
|
#include <Eval.h>
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// Supported operators, borrowed from C++, particularly the precedence.
|
// Supported operators, borrowed from C++, particularly the precedence.
|
||||||
// Note: table is sorted by length of operator string, so searches match
|
// Note: table is sorted by length of operator string, so searches match
|
||||||
// longest first.
|
// longest first.
|
||||||
|
@ -78,11 +79,25 @@ static struct
|
||||||
|
|
||||||
#define NUM_OPERATORS (sizeof (operators) / sizeof (operators[0]))
|
#define NUM_OPERATORS (sizeof (operators) / sizeof (operators[0]))
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Built-in support for some named constants.
|
||||||
|
static bool namedConstants (const std::string& name, Variant& value)
|
||||||
|
{
|
||||||
|
if (name == "true") value = Variant (true);
|
||||||
|
else if (name == "false") value = Variant (false);
|
||||||
|
else if (name == "pi") value = Variant (3.14159165);
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
Eval::Eval ()
|
Eval::Eval ()
|
||||||
: _ambiguity (true)
|
: _ambiguity (true)
|
||||||
, _debug (false)
|
, _debug (false)
|
||||||
{
|
{
|
||||||
|
addSource (namedConstants);
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -233,6 +248,8 @@ void Eval::evaluatePostfixStack (
|
||||||
|
|
||||||
values.push_back (left);
|
values.push_back (left);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Literals and identifiers.
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Variant v (token->first);
|
Variant v (token->first);
|
||||||
|
@ -253,6 +270,7 @@ void Eval::evaluatePostfixStack (
|
||||||
|
|
||||||
case Lexer::typeIdentifier:
|
case Lexer::typeIdentifier:
|
||||||
{
|
{
|
||||||
|
bool found = false;
|
||||||
std::vector <bool (*)(const std::string&, Variant&)>::const_iterator source;
|
std::vector <bool (*)(const std::string&, Variant&)>::const_iterator source;
|
||||||
for (source = _sources.begin (); source != _sources.end (); ++source)
|
for (source = _sources.begin (); source != _sources.end (); ++source)
|
||||||
{
|
{
|
||||||
|
@ -260,12 +278,13 @@ void Eval::evaluatePostfixStack (
|
||||||
{
|
{
|
||||||
if (_debug)
|
if (_debug)
|
||||||
std::cout << "# [" << values.size () << "] eval source '" << token->first << "' --> '" << (std::string) v << "'\n";
|
std::cout << "# [" << values.size () << "] eval source '" << token->first << "' --> '" << (std::string) v << "'\n";
|
||||||
|
found = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// An identifier that fails lookup is a string.
|
// An identifier that fails lookup is a string.
|
||||||
if (source == _sources.end ())
|
if (!found)
|
||||||
{
|
{
|
||||||
v.cast (Variant::type_string);
|
v.cast (Variant::type_string);
|
||||||
if (_debug)
|
if (_debug)
|
||||||
|
|
|
@ -35,16 +35,18 @@ Context context;
|
||||||
// A few hard-coded symbols.
|
// A few hard-coded symbols.
|
||||||
bool get (const std::string& name, Variant& value)
|
bool get (const std::string& name, Variant& value)
|
||||||
{
|
{
|
||||||
if (name == "pi") {value = Variant (3.14159165); return true;}
|
if (name == "x")
|
||||||
else if (name == "x") {value = Variant (true); return true;}
|
value = Variant (true);
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
|
||||||
return false;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
int main (int argc, char** argv)
|
int main (int argc, char** argv)
|
||||||
{
|
{
|
||||||
UnitTest t (43);
|
UnitTest t (46);
|
||||||
|
|
||||||
// Test the source independently.
|
// Test the source independently.
|
||||||
Variant v;
|
Variant v;
|
||||||
|
@ -54,10 +56,6 @@ int main (int argc, char** argv)
|
||||||
t.is (v.type (), Variant::type_boolean, "get(x) --> boolean");
|
t.is (v.type (), Variant::type_boolean, "get(x) --> boolean");
|
||||||
t.is (v.get_bool (), true, "get(x) --> true");
|
t.is (v.get_bool (), true, "get(x) --> true");
|
||||||
|
|
||||||
t.ok (get ("pi", v), "true <-- get(pi)");
|
|
||||||
t.is (v.type (), Variant::type_real, "get(pi) --> real");
|
|
||||||
t.is (v.get_real (), 3.141592, 0.00001, "get(pi) --> 3.14159265");
|
|
||||||
|
|
||||||
Eval e;
|
Eval e;
|
||||||
e.addSource (get);
|
e.addSource (get);
|
||||||
Variant result;
|
Variant result;
|
||||||
|
@ -138,6 +136,20 @@ int main (int argc, char** argv)
|
||||||
t.is (result.type (), Variant::type_integer, "infix '2*3+1' --> integer");
|
t.is (result.type (), Variant::type_integer, "infix '2*3+1' --> integer");
|
||||||
t.is (result.get_integer (), 7, "infix '2*3+1' --> 7");
|
t.is (result.get_integer (), 7, "infix '2*3+1' --> 7");
|
||||||
|
|
||||||
|
// TW-1254 - Unary minus support.
|
||||||
|
e.evaluateInfixExpression ("2--3", result);
|
||||||
|
t.is (result.type (), Variant::type_integer, "infix '2--3' --> integer");
|
||||||
|
t.is (result.get_integer (), 5, "infix '2--3' --> 5");
|
||||||
|
|
||||||
|
//e.debug ();
|
||||||
|
e.evaluateInfixExpression ("!false", result);
|
||||||
|
t.is (result.type (), Variant::type_boolean, "infix '!false' --> boolean");
|
||||||
|
t.is (result.get_bool (), true, "infix '!false' --> true");
|
||||||
|
|
||||||
|
e.evaluateInfixExpression ("!true", result);
|
||||||
|
t.is (result.type (), Variant::type_boolean, "infix '!true' --> boolean");
|
||||||
|
t.is (result.get_bool (), false, "infix '!true' --> false");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue