use std::borrow::Cow;
use crate::bind::BoundExpr;
pub(crate) fn integer_literal(text: &[u8]) -> BoundExpr {
let (negative, digits) = match text.first() {
Some(b'-') => (true, text.get(1..).unwrap_or(&[])),
_ => (false, text),
};
if digits.len() > 2
&& digits.first() == Some(&b'0')
&& digits
.get(1)
.is_some_and(|byte| byte.eq_ignore_ascii_case(&b'x'))
{
let mut value: u64 = 0;
for byte in digits.get(2..).unwrap_or(&[]) {
let digit = (*byte as char).to_digit(16).unwrap_or(0) as u64;
value = value.wrapping_mul(16).wrapping_add(digit);
}
let value = value as i64;
return BoundExpr::Integer(if negative {
value.wrapping_neg()
} else {
value
});
}
let cleaned: Cow<'_, [u8]> = match text.contains(&b'_') {
true => Cow::Owned(text.iter().copied().filter(|byte| *byte != b'_').collect()),
false => Cow::Borrowed(text),
};
let (value, syntax) =
inillucent_value::numeric::atoi64(&cleaned, inillucent_value::TextEncoding::Utf8);
if syntax.is_exact() {
return BoundExpr::Integer(value);
}
let parsed = inillucent_value::numeric::atof(&cleaned, inillucent_value::TextEncoding::Utf8);
BoundExpr::Real(parsed.value)
}