ConditionExpression: Add relation operators
This commit is contained in:
@@ -123,6 +123,10 @@ namespace OpenRA.Support
|
|||||||
Or,
|
Or,
|
||||||
Equals,
|
Equals,
|
||||||
NotEquals,
|
NotEquals,
|
||||||
|
LessThan,
|
||||||
|
LessThanOrEqual,
|
||||||
|
GreaterThan,
|
||||||
|
GreaterThanOrEqual,
|
||||||
|
|
||||||
Invalid
|
Invalid
|
||||||
}
|
}
|
||||||
@@ -130,6 +134,7 @@ namespace OpenRA.Support
|
|||||||
enum Precedence
|
enum Precedence
|
||||||
{
|
{
|
||||||
Unary = 16,
|
Unary = 16,
|
||||||
|
Relation = 9,
|
||||||
Equality = 8,
|
Equality = 8,
|
||||||
And = 4,
|
And = 4,
|
||||||
Or = 3,
|
Or = 3,
|
||||||
@@ -211,6 +216,18 @@ namespace OpenRA.Support
|
|||||||
case TokenType.NotEquals:
|
case TokenType.NotEquals:
|
||||||
yield return new TokenTypeInfo("!=", Precedence.Equality, OperandSides.Both);
|
yield return new TokenTypeInfo("!=", Precedence.Equality, OperandSides.Both);
|
||||||
continue;
|
continue;
|
||||||
|
case TokenType.LessThan:
|
||||||
|
yield return new TokenTypeInfo("<", Precedence.Relation, OperandSides.Both);
|
||||||
|
continue;
|
||||||
|
case TokenType.LessThanOrEqual:
|
||||||
|
yield return new TokenTypeInfo("<=", Precedence.Relation, OperandSides.Both);
|
||||||
|
continue;
|
||||||
|
case TokenType.GreaterThan:
|
||||||
|
yield return new TokenTypeInfo(">", Precedence.Relation, OperandSides.Both);
|
||||||
|
continue;
|
||||||
|
case TokenType.GreaterThanOrEqual:
|
||||||
|
yield return new TokenTypeInfo(">=", Precedence.Relation, OperandSides.Both);
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new InvalidProgramException("CreateTokenTypeInfoEnumeration is missing a TokenTypeInfo entry for TokenType.{0}".F(
|
throw new InvalidProgramException("CreateTokenTypeInfoEnumeration is missing a TokenTypeInfo entry for TokenType.{0}".F(
|
||||||
@@ -258,6 +275,26 @@ namespace OpenRA.Support
|
|||||||
|
|
||||||
return TokenType.Not;
|
return TokenType.Not;
|
||||||
|
|
||||||
|
case '<':
|
||||||
|
i++;
|
||||||
|
if (i < expression.Length && expression[i] == '=')
|
||||||
|
{
|
||||||
|
i++;
|
||||||
|
return TokenType.LessThanOrEqual;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TokenType.LessThan;
|
||||||
|
|
||||||
|
case '>':
|
||||||
|
i++;
|
||||||
|
if (i < expression.Length && expression[i] == '=')
|
||||||
|
{
|
||||||
|
i++;
|
||||||
|
return TokenType.GreaterThanOrEqual;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TokenType.GreaterThan;
|
||||||
|
|
||||||
case '=':
|
case '=':
|
||||||
i++;
|
i++;
|
||||||
if (i < expression.Length && expression[i] == '=')
|
if (i < expression.Length && expression[i] == '=')
|
||||||
@@ -625,6 +662,38 @@ namespace OpenRA.Support
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case TokenType.LessThan:
|
||||||
|
{
|
||||||
|
var y = ast.Pop(ExpressionType.Int);
|
||||||
|
var x = ast.Pop(ExpressionType.Int);
|
||||||
|
ast.Push(Expressions.Expression.LessThan(x, y));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
case TokenType.LessThanOrEqual:
|
||||||
|
{
|
||||||
|
var y = ast.Pop(ExpressionType.Int);
|
||||||
|
var x = ast.Pop(ExpressionType.Int);
|
||||||
|
ast.Push(Expressions.Expression.LessThanOrEqual(x, y));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
case TokenType.GreaterThan:
|
||||||
|
{
|
||||||
|
var y = ast.Pop(ExpressionType.Int);
|
||||||
|
var x = ast.Pop(ExpressionType.Int);
|
||||||
|
ast.Push(Expressions.Expression.GreaterThan(x, y));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
case TokenType.GreaterThanOrEqual:
|
||||||
|
{
|
||||||
|
var y = ast.Pop(ExpressionType.Int);
|
||||||
|
var x = ast.Pop(ExpressionType.Int);
|
||||||
|
ast.Push(Expressions.Expression.GreaterThanOrEqual(x, y));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
case TokenType.Number:
|
case TokenType.Number:
|
||||||
{
|
{
|
||||||
ast.Push(Expressions.Expression.Constant(((NumberToken)t).Value));
|
ast.Push(Expressions.Expression.Constant(((NumberToken)t).Value));
|
||||||
|
|||||||
@@ -146,8 +146,67 @@ namespace OpenRA.Test
|
|||||||
AssertValue("!-5", 1);
|
AssertValue("!-5", 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestCase(TestName = "Precedence")]
|
[TestCase(TestName = "Relation operations")]
|
||||||
public void TestPrecedence()
|
public void TestRelations()
|
||||||
|
{
|
||||||
|
AssertValue("2 < 5", 1);
|
||||||
|
AssertValue("0 < 5", 1);
|
||||||
|
AssertValue("5 < 2", 0);
|
||||||
|
AssertValue("5 < 5", 0);
|
||||||
|
AssertValue("-5 < 0", 1);
|
||||||
|
AssertValue("-2 < -5", 0);
|
||||||
|
AssertValue("-5 < -2", 1);
|
||||||
|
AssertValue("-5 < -5", 0);
|
||||||
|
AssertValue("-7 < 5", 1);
|
||||||
|
AssertValue("0 <= 5", 1);
|
||||||
|
AssertValue("2 <= 5", 1);
|
||||||
|
AssertValue("5 <= 2", 0);
|
||||||
|
AssertValue("5 <= 5", 1);
|
||||||
|
AssertValue("5 <= 0", 0);
|
||||||
|
AssertValue("-2 <= -5", 0);
|
||||||
|
AssertValue("-5 <= -2", 1);
|
||||||
|
AssertValue("-5 <= -5", 1);
|
||||||
|
AssertValue("-7 <= 5", 1);
|
||||||
|
AssertValue("0 <= -5", 0);
|
||||||
|
AssertValue("-5 <= 0", 1);
|
||||||
|
AssertValue("5 > 2", 1);
|
||||||
|
AssertValue("0 > 5", 0);
|
||||||
|
AssertValue("2 > 5", 0);
|
||||||
|
AssertValue("5 > 5", 0);
|
||||||
|
AssertValue("5 > 0", 1);
|
||||||
|
AssertValue("-2 > -5", 1);
|
||||||
|
AssertValue("-7 > -5", 0);
|
||||||
|
AssertValue("-5 > -5", 0);
|
||||||
|
AssertValue("-4 > -5", 1);
|
||||||
|
AssertValue("5 >= 0", 1);
|
||||||
|
AssertValue("0 >= 5", 0);
|
||||||
|
AssertValue("5 >= 2", 1);
|
||||||
|
AssertValue("2 >= 5", 0);
|
||||||
|
AssertValue("5 >= 5", 1);
|
||||||
|
AssertValue("-5 >= 0", 0);
|
||||||
|
AssertValue("0 >= -5", 1);
|
||||||
|
AssertValue("-7 >= 5", 0);
|
||||||
|
AssertValue("-5 >= -5", 1);
|
||||||
|
AssertValue("-4 >= -5", 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestCase(TestName = "Relation Mixed Precedence")]
|
||||||
|
public void TestRelationMixedPrecedence()
|
||||||
|
{
|
||||||
|
AssertValue("5 <= 5 && 2 > 1", 1);
|
||||||
|
AssertValue("5 > 5 || 2 > 1", 1);
|
||||||
|
AssertValue("5 > 5 || 1 > 1", 0);
|
||||||
|
AssertValue("5 <= 5 == 2 > 1", 1);
|
||||||
|
AssertValue("5 > 5 == 2 > 1", 0);
|
||||||
|
AssertValue("5 > 5 == 1 > 1", 1);
|
||||||
|
AssertValue("5 <= 5 != 2 > 1", 0);
|
||||||
|
AssertValue("5 > 5 != 2 > 1", 1);
|
||||||
|
AssertValue("5 > 5 != 1 > 1", 0);
|
||||||
|
AssertValue("5 > 5 != 1 >= 1", 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestCase(TestName = "AND-OR Precedence")]
|
||||||
|
public void TestAndOrPrecedence()
|
||||||
{
|
{
|
||||||
AssertTrue("true && false || true");
|
AssertTrue("true && false || true");
|
||||||
AssertFalse("false || false && true");
|
AssertFalse("false || false && true");
|
||||||
|
|||||||
@@ -22,7 +22,7 @@
|
|||||||
800: rank-veteran
|
800: rank-veteran
|
||||||
1600: rank-veteran
|
1600: rank-veteran
|
||||||
GrantCondition@RANK-ELITE:
|
GrantCondition@RANK-ELITE:
|
||||||
RequiresCondition: rank-veteran == 4
|
RequiresCondition: rank-veteran >= 4
|
||||||
Condition: rank-elite
|
Condition: rank-elite
|
||||||
DamageMultiplier@RANK-1:
|
DamageMultiplier@RANK-1:
|
||||||
RequiresCondition: rank-veteran == 1
|
RequiresCondition: rank-veteran == 1
|
||||||
|
|||||||
@@ -22,7 +22,7 @@
|
|||||||
800: rank-veteran
|
800: rank-veteran
|
||||||
1600: rank-veteran
|
1600: rank-veteran
|
||||||
GrantCondition@RANK-ELITE:
|
GrantCondition@RANK-ELITE:
|
||||||
RequiresCondition: rank-veteran == 4
|
RequiresCondition: rank-veteran >= 4
|
||||||
Condition: rank-elite
|
Condition: rank-elite
|
||||||
DamageMultiplier@RANK-1:
|
DamageMultiplier@RANK-1:
|
||||||
RequiresCondition: rank-veteran == 1
|
RequiresCondition: rank-veteran == 1
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
800: rank-veteran
|
800: rank-veteran
|
||||||
1600: rank-veteran
|
1600: rank-veteran
|
||||||
GrantCondition@RANK-ELITE:
|
GrantCondition@RANK-ELITE:
|
||||||
RequiresCondition: rank-veteran == 4
|
RequiresCondition: rank-veteran >= 4
|
||||||
Condition: rank-elite
|
Condition: rank-elite
|
||||||
DamageMultiplier@RANK-1:
|
DamageMultiplier@RANK-1:
|
||||||
RequiresCondition: rank-veteran == 1
|
RequiresCondition: rank-veteran == 1
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
RequiresCondition: rank == 1
|
RequiresCondition: rank == 1
|
||||||
Condition: rank-veteran
|
Condition: rank-veteran
|
||||||
GrantCondition@RANK-ELITE:
|
GrantCondition@RANK-ELITE:
|
||||||
RequiresCondition: rank == 2
|
RequiresCondition: rank >= 2
|
||||||
Condition: rank-elite
|
Condition: rank-elite
|
||||||
FirepowerMultiplier@VETERAN:
|
FirepowerMultiplier@VETERAN:
|
||||||
RequiresCondition: rank-veteran
|
RequiresCondition: rank-veteran
|
||||||
|
|||||||
Reference in New Issue
Block a user