Add parse_int and parse_float.
This commit is contained in:
parent
035b9cb839
commit
ed38b50490
@ -24,6 +24,7 @@ New features
|
|||||||
|
|
||||||
* Plugins support via procedural macros.
|
* Plugins support via procedural macros.
|
||||||
* Scripted functions are allowed in packages.
|
* Scripted functions are allowed in packages.
|
||||||
|
* `parse_int` and `parse_float` functions.
|
||||||
|
|
||||||
|
|
||||||
Version 0.18.3
|
Version 0.18.3
|
||||||
|
@ -9,11 +9,11 @@ Integer Functions
|
|||||||
The following standard functions (defined in the [`BasicMathPackage`][packages] but excluded if using a [raw `Engine`])
|
The following standard functions (defined in the [`BasicMathPackage`][packages] but excluded if using a [raw `Engine`])
|
||||||
operate on `i8`, `i16`, `i32`, `i64`, `f32` and `f64` only:
|
operate on `i8`, `i16`, `i32`, `i64`, `f32` and `f64` only:
|
||||||
|
|
||||||
| Function | Description |
|
| Function | No available under | Description |
|
||||||
| ------------ | ----------------------------------------------------------------------- |
|
| -------- | :----------------: | ---------------------------------------------------------------------- |
|
||||||
| `abs` | absolute value |
|
| `abs` | | absolute value |
|
||||||
| `sign` | returns -1 (`INT`) if the number is negative, +1 if positive, 0 if zero |
|
| `sign` | | return -1 (`INT`) if the number is negative, +1 if positive, 0 if zero |
|
||||||
| [`to_float`] | converts an integer type to `FLOAT` |
|
|
||||||
|
|
||||||
Floating-Point Functions
|
Floating-Point Functions
|
||||||
-----------------------
|
-----------------------
|
||||||
@ -31,3 +31,16 @@ operate on `f64` only:
|
|||||||
| Rounding | `floor`, `ceiling`, `round`, `int`, `fraction` methods and properties |
|
| Rounding | `floor`, `ceiling`, `round`, `int`, `fraction` methods and properties |
|
||||||
| Conversion | [`to_int`] |
|
| Conversion | [`to_int`] |
|
||||||
| Testing | `is_nan`, `is_finite`, `is_infinite` methods and properties |
|
| Testing | `is_nan`, `is_finite`, `is_infinite` methods and properties |
|
||||||
|
|
||||||
|
|
||||||
|
Conversion Functions
|
||||||
|
-------------------
|
||||||
|
|
||||||
|
The following standard functions (defined in the [`BasicMathPackage`][packages] but excluded if using a [raw `Engine`])
|
||||||
|
parse numbers:
|
||||||
|
|
||||||
|
| Function | No available under | Description |
|
||||||
|
| --------------- | :----------------: | -------------------------------------------------- |
|
||||||
|
| [`to_float`] | [`no_float`] | convert an integer type to `FLOAT` |
|
||||||
|
| [`parse_int`] | | convert a [string] to `INT` with an optional radix |
|
||||||
|
| [`parse_float`] | [`no_float`] | convert a [string] to `FLOAT` |
|
||||||
|
@ -67,6 +67,9 @@ def_package!(crate:BasicMathPackage:"Basic mathematic functions.", lib, {
|
|||||||
|
|
||||||
reg_functions!(lib += basic_to_int::to_int(char));
|
reg_functions!(lib += basic_to_int::to_int(char));
|
||||||
|
|
||||||
|
set_exported_fn!(lib, "parse_int", parse_int);
|
||||||
|
set_exported_fn!(lib, "parse_int", parse_int_radix);
|
||||||
|
|
||||||
#[cfg(not(feature = "only_i32"))]
|
#[cfg(not(feature = "only_i32"))]
|
||||||
#[cfg(not(feature = "only_i64"))]
|
#[cfg(not(feature = "only_i64"))]
|
||||||
{
|
{
|
||||||
@ -223,6 +226,21 @@ mod float_functions {
|
|||||||
Ok((x.trunc() as INT).into())
|
Ok((x.trunc() as INT).into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[rhai_fn(return_raw)]
|
||||||
|
#[inline]
|
||||||
|
pub fn parse_float(s: &str) -> Result<Dynamic, Box<EvalAltResult>> {
|
||||||
|
s.trim()
|
||||||
|
.parse::<FLOAT>()
|
||||||
|
.map(Into::<Dynamic>::into)
|
||||||
|
.map_err(|err| {
|
||||||
|
EvalAltResult::ErrorArithmetic(
|
||||||
|
format!("Error parsing floating-point number '{}': {}", s, err),
|
||||||
|
Position::none(),
|
||||||
|
)
|
||||||
|
.into()
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "no_float"))]
|
#[cfg(not(feature = "no_float"))]
|
||||||
@ -249,3 +267,30 @@ gen_conversion_functions!(numbers_to_int => to_int (i8, u8, i16, u16, i32, u32,
|
|||||||
#[cfg(not(feature = "only_i64"))]
|
#[cfg(not(feature = "only_i64"))]
|
||||||
#[cfg(not(target_arch = "wasm32"))]
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
gen_conversion_functions!(num_128_to_int => to_int (i128, u128) -> INT);
|
gen_conversion_functions!(num_128_to_int => to_int (i128, u128) -> INT);
|
||||||
|
|
||||||
|
#[export_fn(return_raw)]
|
||||||
|
fn parse_int_radix(s: &str, radix: INT) -> Result<Dynamic, Box<EvalAltResult>> {
|
||||||
|
if radix < 2 || radix > 36 {
|
||||||
|
return EvalAltResult::ErrorArithmetic(
|
||||||
|
format!("Invalid radix: '{}'", radix),
|
||||||
|
Position::none(),
|
||||||
|
)
|
||||||
|
.into();
|
||||||
|
}
|
||||||
|
|
||||||
|
INT::from_str_radix(s.trim(), radix as u32)
|
||||||
|
.map(Into::<Dynamic>::into)
|
||||||
|
.map_err(|err| {
|
||||||
|
EvalAltResult::ErrorArithmetic(
|
||||||
|
format!("Error parsing integer number '{}': {}", s, err),
|
||||||
|
Position::none(),
|
||||||
|
)
|
||||||
|
.into()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
#[export_fn(return_raw)]
|
||||||
|
#[inline(always)]
|
||||||
|
fn parse_int(s: &str) -> Result<Dynamic, Box<EvalAltResult>> {
|
||||||
|
parse_int_radix(s, 10)
|
||||||
|
}
|
||||||
|
@ -151,6 +151,7 @@ fn to_string<T: Display>(x: &mut T) -> ImmutableString {
|
|||||||
fn to_debug<T: Debug>(x: &mut T) -> ImmutableString {
|
fn to_debug<T: Debug>(x: &mut T) -> ImmutableString {
|
||||||
format!("{:?}", x).into()
|
format!("{:?}", x).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "no_object"))]
|
#[cfg(not(feature = "no_object"))]
|
||||||
mod format_map {
|
mod format_map {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
@ -20,6 +20,15 @@ fn test_float() -> Result<(), Box<EvalAltResult>> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_float_parse() -> Result<(), Box<EvalAltResult>> {
|
||||||
|
let engine = Engine::new();
|
||||||
|
|
||||||
|
assert!((engine.eval::<FLOAT>(r#"parse_float("9.9999")"#)? - 9.9999 as FLOAT).abs() < EPSILON);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[cfg(not(feature = "no_object"))]
|
#[cfg(not(feature = "no_object"))]
|
||||||
fn test_struct_with_float() -> Result<(), Box<EvalAltResult>> {
|
fn test_struct_with_float() -> Result<(), Box<EvalAltResult>> {
|
||||||
|
@ -108,3 +108,14 @@ fn test_math() -> Result<(), Box<EvalAltResult>> {
|
|||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_math_parse() -> Result<(), Box<EvalAltResult>> {
|
||||||
|
let engine = Engine::new();
|
||||||
|
|
||||||
|
assert_eq!(engine.eval::<INT>(r#"parse_int("42")"#)?, 42);
|
||||||
|
assert_eq!(engine.eval::<INT>(r#"parse_int("42", 16)"#)?, 0x42);
|
||||||
|
assert_eq!(engine.eval::<INT>(r#"parse_int("abcdef", 16)"#)?, 0xabcdef);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user