Handle UnsignedLiteral in the Reduce operations
parent
f0fb0174b6
commit
d474a0ed9c
|
@ -3520,6 +3520,8 @@ func CloneExpr(expr Expr) Expr {
|
|||
return &DurationLiteral{Val: expr.Val}
|
||||
case *IntegerLiteral:
|
||||
return &IntegerLiteral{Val: expr.Val}
|
||||
case *UnsignedLiteral:
|
||||
return &UnsignedLiteral{Val: expr.Val}
|
||||
case *NumberLiteral:
|
||||
return &NumberLiteral{Val: expr.Val}
|
||||
case *ParenExpr:
|
||||
|
@ -4407,6 +4409,8 @@ func reduceBinaryExpr(expr *BinaryExpr, valuer Valuer) Expr {
|
|||
return reduceBinaryExprDurationLHS(op, lhs, rhs, loc)
|
||||
case *IntegerLiteral:
|
||||
return reduceBinaryExprIntegerLHS(op, lhs, rhs, loc)
|
||||
case *UnsignedLiteral:
|
||||
return reduceBinaryExprUnsignedLHS(op, lhs, rhs)
|
||||
case *NilLiteral:
|
||||
return reduceBinaryExprNilLHS(op, lhs, rhs)
|
||||
case *NumberLiteral:
|
||||
|
@ -4550,6 +4554,19 @@ func reduceBinaryExprIntegerLHS(op Token, lhs *IntegerLiteral, rhs Expr, loc *ti
|
|||
case LTE:
|
||||
return &BooleanLiteral{Val: lhs.Val <= rhs.Val}
|
||||
}
|
||||
case *UnsignedLiteral:
|
||||
// Comparisons between an unsigned and integer literal will not involve
|
||||
// a cast if the integer is negative as that will have an improper result.
|
||||
// Look for those situations here.
|
||||
if lhs.Val < 0 {
|
||||
switch op {
|
||||
case LT, LTE:
|
||||
return &BooleanLiteral{Val: true}
|
||||
case GT, GTE:
|
||||
return &BooleanLiteral{Val: false}
|
||||
}
|
||||
}
|
||||
return reduceBinaryExprUnsignedLHS(op, &UnsignedLiteral{Val: uint64(lhs.Val)}, rhs)
|
||||
case *DurationLiteral:
|
||||
// Treat the integer as a timestamp.
|
||||
switch op {
|
||||
|
@ -4580,6 +4597,58 @@ func reduceBinaryExprIntegerLHS(op Token, lhs *IntegerLiteral, rhs Expr, loc *ti
|
|||
return &BinaryExpr{Op: op, LHS: lhs, RHS: rhs}
|
||||
}
|
||||
|
||||
func reduceBinaryExprUnsignedLHS(op Token, lhs *UnsignedLiteral, rhs Expr) Expr {
|
||||
switch rhs := rhs.(type) {
|
||||
case *NumberLiteral:
|
||||
return reduceBinaryExprNumberLHS(op, &NumberLiteral{Val: float64(lhs.Val)}, rhs)
|
||||
case *IntegerLiteral:
|
||||
// Comparisons between an unsigned and integer literal will not involve
|
||||
// a cast if the integer is negative as that will have an improper result.
|
||||
// Look for those situations here.
|
||||
if rhs.Val < 0 {
|
||||
switch op {
|
||||
case LT, LTE:
|
||||
return &BooleanLiteral{Val: false}
|
||||
case GT, GTE:
|
||||
return &BooleanLiteral{Val: true}
|
||||
}
|
||||
}
|
||||
return reduceBinaryExprUnsignedLHS(op, lhs, &UnsignedLiteral{Val: uint64(rhs.Val)})
|
||||
case *UnsignedLiteral:
|
||||
switch op {
|
||||
case ADD:
|
||||
return &UnsignedLiteral{Val: lhs.Val + rhs.Val}
|
||||
case SUB:
|
||||
return &UnsignedLiteral{Val: lhs.Val - rhs.Val}
|
||||
case MUL:
|
||||
return &UnsignedLiteral{Val: lhs.Val * rhs.Val}
|
||||
case DIV:
|
||||
if rhs.Val == 0 {
|
||||
return &UnsignedLiteral{Val: 0}
|
||||
}
|
||||
return &UnsignedLiteral{Val: lhs.Val / rhs.Val}
|
||||
case MOD:
|
||||
if rhs.Val == 0 {
|
||||
return &UnsignedLiteral{Val: 0}
|
||||
}
|
||||
return &UnsignedLiteral{Val: lhs.Val % rhs.Val}
|
||||
case EQ:
|
||||
return &BooleanLiteral{Val: lhs.Val == rhs.Val}
|
||||
case NEQ:
|
||||
return &BooleanLiteral{Val: lhs.Val != rhs.Val}
|
||||
case GT:
|
||||
return &BooleanLiteral{Val: lhs.Val > rhs.Val}
|
||||
case GTE:
|
||||
return &BooleanLiteral{Val: lhs.Val >= rhs.Val}
|
||||
case LT:
|
||||
return &BooleanLiteral{Val: lhs.Val < rhs.Val}
|
||||
case LTE:
|
||||
return &BooleanLiteral{Val: lhs.Val <= rhs.Val}
|
||||
}
|
||||
}
|
||||
return &BinaryExpr{Op: op, LHS: lhs, RHS: rhs}
|
||||
}
|
||||
|
||||
func reduceBinaryExprNilLHS(op Token, lhs *NilLiteral, rhs Expr) Expr {
|
||||
switch op {
|
||||
case EQ, NEQ:
|
||||
|
@ -4646,6 +4715,8 @@ func reduceBinaryExprNumberLHS(op Token, lhs *NumberLiteral, rhs Expr) Expr {
|
|||
case LTE:
|
||||
return &BooleanLiteral{Val: lhs.Val <= float64(rhs.Val)}
|
||||
}
|
||||
case *UnsignedLiteral:
|
||||
return reduceBinaryExprNumberLHS(op, lhs, &NumberLiteral{Val: float64(rhs.Val)})
|
||||
case *NilLiteral:
|
||||
return &BooleanLiteral{Val: false}
|
||||
}
|
||||
|
|
|
@ -1178,6 +1178,34 @@ func TestReduce(t *testing.T) {
|
|||
{in: `4 < 6`, out: `true`},
|
||||
{in: `4 <= 4`, out: `true`},
|
||||
{in: `4 AND 5`, out: `4 AND 5`},
|
||||
{in: `-1 = 9223372036854775808`, out: `false`},
|
||||
{in: `-1 != 9223372036854775808`, out: `true`},
|
||||
{in: `-1 < 9223372036854775808`, out: `true`},
|
||||
{in: `-1 <= 9223372036854775808`, out: `true`},
|
||||
{in: `-1 > 9223372036854775808`, out: `false`},
|
||||
{in: `-1 >= 9223372036854775808`, out: `false`},
|
||||
{in: `9223372036854775808 = -1`, out: `false`},
|
||||
{in: `9223372036854775808 != -1`, out: `true`},
|
||||
{in: `9223372036854775808 < -1`, out: `false`},
|
||||
{in: `9223372036854775808 <= -1`, out: `false`},
|
||||
{in: `9223372036854775808 > -1`, out: `true`},
|
||||
{in: `9223372036854775808 >= -1`, out: `true`},
|
||||
{in: `9223372036854775808 = 9223372036854775808`, out: `true`},
|
||||
{in: `9223372036854775808 != 9223372036854775808`, out: `false`},
|
||||
{in: `9223372036854775808 < 9223372036854775808`, out: `false`},
|
||||
{in: `9223372036854775808 <= 9223372036854775808`, out: `true`},
|
||||
{in: `9223372036854775808 > 9223372036854775808`, out: `false`},
|
||||
{in: `9223372036854775808 >= 9223372036854775808`, out: `true`},
|
||||
{in: `9223372036854775809 = 9223372036854775808`, out: `false`},
|
||||
{in: `9223372036854775809 != 9223372036854775808`, out: `true`},
|
||||
{in: `9223372036854775809 < 9223372036854775808`, out: `false`},
|
||||
{in: `9223372036854775809 <= 9223372036854775808`, out: `false`},
|
||||
{in: `9223372036854775809 > 9223372036854775808`, out: `true`},
|
||||
{in: `9223372036854775809 >= 9223372036854775808`, out: `true`},
|
||||
{in: `9223372036854775808 / 0`, out: `0`},
|
||||
{in: `9223372036854775808 + 1`, out: `9223372036854775809`},
|
||||
{in: `9223372036854775808 - 1`, out: `9223372036854775807`},
|
||||
{in: `9223372036854775809 - 9223372036854775808`, out: `1`},
|
||||
|
||||
// Boolean literals.
|
||||
{in: `true AND false`, out: `false`},
|
||||
|
|
Loading…
Reference in New Issue