ExpressionParser: Fix negative literals and support unary minus operator.
This commit is contained in:
parent
7cf903a209
commit
ccac3f1e49
|
@ -572,6 +572,20 @@ public:
|
||||||
int GetArity() const override { return 3; }
|
int GetArity() const override { return 3; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class UnaryMinusExpression : public FunctionExpression
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ControlState GetValue() const override
|
||||||
|
{
|
||||||
|
// Subtraction for clarity:
|
||||||
|
return 0.0 - GetArg(0).GetValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetValue(ControlState value) override {}
|
||||||
|
std::string GetFuncName() const override { return "Minus"; }
|
||||||
|
int GetArity() const override { return 1; }
|
||||||
|
};
|
||||||
|
|
||||||
class WhileExpression : public FunctionExpression
|
class WhileExpression : public FunctionExpression
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -617,6 +631,8 @@ std::unique_ptr<FunctionExpression> MakeFunctionExpression(std::string name)
|
||||||
return std::make_unique<ToggleExpression>();
|
return std::make_unique<ToggleExpression>();
|
||||||
else if ("while" == name)
|
else if ("while" == name)
|
||||||
return std::make_unique<WhileExpression>();
|
return std::make_unique<WhileExpression>();
|
||||||
|
else if ("minus" == name)
|
||||||
|
return std::make_unique<UnaryMinusExpression>();
|
||||||
else
|
else
|
||||||
return std::make_unique<UnknownFunctionExpression>();
|
return std::make_unique<UnknownFunctionExpression>();
|
||||||
}
|
}
|
||||||
|
@ -782,9 +798,8 @@ private:
|
||||||
return tok.type == type;
|
return tok.type == type;
|
||||||
}
|
}
|
||||||
|
|
||||||
ParseResult Atom()
|
ParseResult Atom(const Token& tok)
|
||||||
{
|
{
|
||||||
const Token tok = Chew();
|
|
||||||
switch (tok.type)
|
switch (tok.type)
|
||||||
{
|
{
|
||||||
case TOK_FUNCTION:
|
case TOK_FUNCTION:
|
||||||
|
@ -793,7 +808,7 @@ private:
|
||||||
int arity = func->GetArity();
|
int arity = func->GetArity();
|
||||||
while (arity--)
|
while (arity--)
|
||||||
{
|
{
|
||||||
auto arg = Atom();
|
auto arg = Atom(Chew());
|
||||||
if (arg.status == ParseStatus::SyntaxError)
|
if (arg.status == ParseStatus::SyntaxError)
|
||||||
return arg;
|
return arg;
|
||||||
|
|
||||||
|
@ -819,6 +834,12 @@ private:
|
||||||
{
|
{
|
||||||
return Paren();
|
return Paren();
|
||||||
}
|
}
|
||||||
|
case TOK_SUB:
|
||||||
|
{
|
||||||
|
// An atom was expected but we got a subtraction symbol.
|
||||||
|
// Interpret it as a unary minus function.
|
||||||
|
return Atom(Token(TOK_FUNCTION, "minus"));
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
return {ParseStatus::SyntaxError};
|
return {ParseStatus::SyntaxError};
|
||||||
}
|
}
|
||||||
|
@ -859,7 +880,7 @@ private:
|
||||||
|
|
||||||
ParseResult Binary(int precedence = 999)
|
ParseResult Binary(int precedence = 999)
|
||||||
{
|
{
|
||||||
ParseResult lhs = Atom();
|
ParseResult lhs = Atom(Chew());
|
||||||
|
|
||||||
if (lhs.status == ParseStatus::SyntaxError)
|
if (lhs.status == ParseStatus::SyntaxError)
|
||||||
return lhs;
|
return lhs;
|
||||||
|
|
Loading…
Reference in New Issue