Merge 'Parse hex integers 2' from Anton Harniakou

Continuation of #1329

Reviewed-by: Jussi Saurio <jussi.saurio@gmail.com>

Closes #1347
This commit is contained in:
Jussi Saurio 2025-04-16 11:13:01 +03:00
commit 913367409e
3 changed files with 28 additions and 7 deletions

View file

@ -1850,7 +1850,7 @@ pub fn translate_expr(
} }
ast::Expr::Literal(lit) => match lit { ast::Expr::Literal(lit) => match lit {
ast::Literal::Numeric(val) => { ast::Literal::Numeric(val) => {
if val.starts_with("0x") { if val.starts_with("0x") || val.starts_with("0X") {
// must be a hex decimal // must be a hex decimal
let int_value = i64::from_str_radix(&val[2..], 16)?; let int_value = i64::from_str_radix(&val[2..], 16)?;
program.emit_insn(Insn::Integer { program.emit_insn(Insn::Integer {
@ -1941,14 +1941,22 @@ pub fn translate_expr(
// Special case: if we're negating "9223372036854775808", this is exactly MIN_INT64 // Special case: if we're negating "9223372036854775808", this is exactly MIN_INT64
// If we don't do this -1 * 9223372036854775808 will overflow and parse will fail // If we don't do this -1 * 9223372036854775808 will overflow and parse will fail
// and trigger conversion to Real. // and trigger conversion to Real.
if numeric_value == "9223372036854775808" { if numeric_value == "9223372036854775808"
|| numeric_value.eq_ignore_ascii_case("0x7fffffffffffffff")
{
program.emit_insn(Insn::Integer { program.emit_insn(Insn::Integer {
value: i64::MIN, value: i64::MIN,
dest: target_register, dest: target_register,
}); });
} else { } else {
let maybe_int = numeric_value.parse::<i64>(); if numeric_value.starts_with("0x") || numeric_value.starts_with("0X") {
if let Ok(value) = maybe_int { // must be a hex decimal
let int_value = i64::from_str_radix(&numeric_value[2..], 16)?;
program.emit_insn(Insn::Integer {
value: -int_value,
dest: target_register,
});
} else if let Ok(value) = numeric_value.parse::<i64>() {
program.emit_insn(Insn::Integer { program.emit_insn(Insn::Integer {
value: value * -1, value: value * -1,
dest: target_register, dest: target_register,
@ -1982,8 +1990,13 @@ pub fn translate_expr(
Ok(target_register) Ok(target_register)
} }
(UnaryOperator::BitwiseNot, ast::Expr::Literal(ast::Literal::Numeric(num_val))) => { (UnaryOperator::BitwiseNot, ast::Expr::Literal(ast::Literal::Numeric(num_val))) => {
let maybe_int = num_val.parse::<i64>(); if num_val.starts_with("0x") || num_val.starts_with("0X") {
if let Ok(val) = maybe_int { let int_value = i64::from_str_radix(&num_val[2..], 16)?;
program.emit_insn(Insn::Integer {
value: !int_value,
dest: target_register,
});
} else if let Ok(val) = num_val.parse::<i64>() {
program.emit_insn(Insn::Integer { program.emit_insn(Insn::Integer {
value: !val, value: !val,
dest: target_register, dest: target_register,

View file

@ -624,10 +624,14 @@ do_execsql_test bitwise-not-text-float {
SELECT ~'823.34' SELECT ~'823.34'
} {-824} } {-824}
do_execsql_test bitwise-not-text-int { do_execsql_test bitwise-not-text-int-1 {
SELECT ~'1234' SELECT ~'1234'
} {-1235} } {-1235}
do_execsql_test bitwise-not-text-int-2 {
SELECT ~0xA
} {-11}
do_execsql_test bitwise-not-scalar-float { do_execsql_test bitwise-not-scalar-float {
SELECT ~abs(693.9) SELECT ~abs(693.9)
} {-694} } {-694}

View file

@ -15,6 +15,10 @@ do_execsql_test select-const-3 {
SELECT 0xDEAF SELECT 0xDEAF
} {57007} } {57007}
do_execsql_test select-const-4 {
SELECT -0xA
} {-10}
do_execsql_test select-true { do_execsql_test select-true {
SELECT true SELECT true
} {1} } {1}