From 40d27df4462650a3e4e40e12a028eda3f8d251f1 Mon Sep 17 00:00:00 2001 From: Kaspar Schleiser Date: Thu, 25 May 2023 10:29:11 +0200 Subject: [PATCH] add hex integer literal parsing support --- Cargo.toml | 1 + src/token/mod.rs | 17 ++++++++++++++++- tests/integration.rs | 6 ++++++ 3 files changed, 23 insertions(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index c497c77..f4353dd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,6 +27,7 @@ regex = { version = "1.5.5", optional = true} serde = { version = "1.0.133", optional = true} serde_derive = { version = "1.0.133", optional = true} rand = { version = "0.8.5", optional = true} +num-traits = "0.2.15" [features] serde_support = ["serde", "serde_derive"] diff --git a/src/token/mod.rs b/src/token/mod.rs index 3bb49cd..865fdf1 100644 --- a/src/token/mod.rs +++ b/src/token/mod.rs @@ -348,7 +348,7 @@ fn partial_tokens_to_tokens(mut tokens: &[PartialToken]) -> EvalexprResult { cutoff = 1; - if let Ok(number) = literal.parse::() { + if let Ok(number) = literal.parse_dec_or_hex::() { Some(Token::Int(number)) } else if let Ok(number) = literal.parse::() { Some(Token::Float(number)) @@ -442,6 +442,21 @@ pub(crate) fn tokenize(string: &str) -> EvalexprResult> { partial_tokens_to_tokens(&str_to_partial_tokens(string)?) } +/// Helper trait to parse strings to integer from both decimal or hex +trait ParseDecOrHex { + fn parse_dec_or_hex(&self) -> Result; +} + +impl ParseDecOrHex for str { + fn parse_dec_or_hex(&self) -> Result { + if self.starts_with("0x") { + T::from_str_radix(&self[2..], 16) + } else { + T::from_str_radix(&self, 10) + } + } +} + #[cfg(test)] mod tests { use crate::token::{char_to_partial_token, tokenize, Token}; diff --git a/tests/integration.rs b/tests/integration.rs index 0c97576..ed9ff18 100644 --- a/tests/integration.rs +++ b/tests/integration.rs @@ -2291,3 +2291,9 @@ fn test_builtin_functions_context() { ))) ); } + +#[test] +fn test_hex() { + assert_eq!(eval("0x3"), Ok(Value::Int(3))); + assert_eq!(eval("0xFF"), Ok(Value::Int(255))); +}