Merge branch 'v1.3-fixes'

This commit is contained in:
Stephen Chung 2021-12-18 18:22:20 +08:00
commit 541ef319bb
6 changed files with 52 additions and 10 deletions

View File

@ -30,6 +30,7 @@ Bug fixes
--------- ---------
* Custom syntax now works properly inside binary expressions and with method calls. * Custom syntax now works properly inside binary expressions and with method calls.
* Hex numbers with the high-bit set now parse correctly into negative integer numbers.
Enhancements Enhancements
------------ ------------

View File

@ -98,6 +98,20 @@ pub type INT = i64;
#[cfg(feature = "only_i32")] #[cfg(feature = "only_i32")]
pub type INT = i32; pub type INT = i32;
/// The system base integer type. It is defined as [`u64`].
///
/// If the `only_i32` feature is enabled, this will be [`u32`] instead.
#[cfg(not(feature = "only_i32"))]
#[allow(non_camel_case_types)]
type INT_BASE = u64;
/// The system integer base type.
/// It is defined as [`u32`] since the `only_i32` feature is used.
///
/// If the `only_i32` feature is not used, this will be `u64` instead.
#[cfg(feature = "only_i32")]
#[allow(non_camel_case_types)]
type INT_BASE = u32;
/// The system floating-point type. It is defined as [`f64`]. /// The system floating-point type. It is defined as [`f64`].
/// Not available under `no_float`. /// Not available under `no_float`.
/// ///

View File

@ -1,7 +1,7 @@
#![allow(non_snake_case)] #![allow(non_snake_case)]
use crate::plugin::*; use crate::plugin::*;
use crate::{def_package, Position, INT}; use crate::{def_package, Position, INT, INT_BASE};
#[cfg(feature = "no_std")] #[cfg(feature = "no_std")]
use std::prelude::v1::*; use std::prelude::v1::*;
@ -120,13 +120,15 @@ mod int_functions {
.into()); .into());
} }
INT::from_str_radix(string.trim(), radix as u32).map_err(|err| { INT_BASE::from_str_radix(string.trim(), radix as u32)
EvalAltResult::ErrorArithmetic( .map(|v| v as INT)
format!("Error parsing integer number '{}': {}", string, err), .map_err(|err| {
Position::NONE, EvalAltResult::ErrorArithmetic(
) format!("Error parsing integer number '{}': {}", string, err),
.into() Position::NONE,
}) )
.into()
})
} }
#[rhai_fn(name = "parse_int", return_raw)] #[rhai_fn(name = "parse_int", return_raw)]
pub fn parse_int(string: &str) -> Result<INT, Box<EvalAltResult>> { pub fn parse_int(string: &str) -> Result<INT, Box<EvalAltResult>> {

View File

@ -5,7 +5,7 @@ use crate::engine::{
KEYWORD_FN_PTR_CURRY, KEYWORD_IS_DEF_VAR, KEYWORD_PRINT, KEYWORD_THIS, KEYWORD_TYPE_OF, KEYWORD_FN_PTR_CURRY, KEYWORD_IS_DEF_VAR, KEYWORD_PRINT, KEYWORD_THIS, KEYWORD_TYPE_OF,
}; };
use crate::func::native::OnParseTokenCallback; use crate::func::native::OnParseTokenCallback;
use crate::{Engine, LexError, StaticVec, INT}; use crate::{Engine, LexError, StaticVec, INT, INT_BASE};
#[cfg(feature = "no_std")] #[cfg(feature = "no_std")]
use std::prelude::v1::*; use std::prelude::v1::*;
use std::{ use std::{
@ -1530,7 +1530,8 @@ fn get_next_token_inner(
.filter(|&&c| c != NUMBER_SEPARATOR) .filter(|&&c| c != NUMBER_SEPARATOR)
.collect(); .collect();
INT::from_str_radix(&out, radix) INT_BASE::from_str_radix(&out, radix)
.map(|v| v as INT)
.map(Token::IntegerConstant) .map(Token::IntegerConstant)
.unwrap_or_else(|_| { .unwrap_or_else(|_| {
Token::LexError(LERR::MalformedNumber(result.into_iter().collect())) Token::LexError(LERR::MalformedNumber(result.into_iter().collect()))

View File

@ -162,6 +162,13 @@ fn test_blobs_parse() -> Result<(), Box<EvalAltResult>> {
0x1cf588 0x1cf588
); );
assert_eq!(
engine.eval::<Blob>(
"let x = blob(16, 0); write_be(x, 0, 8, 0x1234567890abcdef); write_be(x, 8, 8, 0xabcdef1234567890); x"
)?,
vec![0x12, 0x34, 0x56, 0x78, 0x90, 0xab, 0xcd, 0xef, 0xab, 0xcd, 0xef, 0x12, 0x34, 0x56, 0x78, 0x90]
);
Ok(()) Ok(())
} }

View File

@ -27,6 +27,11 @@ fn test_hex_literal() -> Result<(), Box<EvalAltResult>> {
assert_eq!(engine.eval::<INT>("let x = 0Xf; x")?, 15); assert_eq!(engine.eval::<INT>("let x = 0Xf; x")?, 15);
assert_eq!(engine.eval::<INT>("let x = 0xff; x")?, 255); assert_eq!(engine.eval::<INT>("let x = 0xff; x")?, 255);
#[cfg(not(feature = "only_i32"))]
assert_eq!(engine.eval::<INT>("let x = 0xffffffffffffffff; x")?, -1);
#[cfg(feature = "only_i32")]
assert_eq!(engine.eval::<INT>("let x = 0xffffffff; x")?, -1);
Ok(()) Ok(())
} }
@ -51,6 +56,18 @@ fn test_binary_literal() -> Result<(), Box<EvalAltResult>> {
engine.eval::<INT>("let x = 0b0011_1100_1010_0101; x")?, engine.eval::<INT>("let x = 0b0011_1100_1010_0101; x")?,
15525 15525
); );
#[cfg(not(feature = "only_i32"))]
assert_eq!(
engine.eval::<INT>(
"let x = 0b11111111_11111111_11111111_11111111_11111111_11111111_11111111_11111111; x"
)?,
-1
);
#[cfg(feature = "only_i32")]
assert_eq!(
engine.eval::<INT>("let x = 0b11111111_11111111_11111111_11111111; x")?,
-1
);
Ok(()) Ok(())
} }