Add only_i32
and only_i64
features.
This commit is contained in:
406
src/builtin.rs
406
src/builtin.rs
@@ -4,26 +4,38 @@
|
||||
use crate::any::Any;
|
||||
use crate::engine::Engine;
|
||||
use crate::fn_register::RegisterFn;
|
||||
use crate::parser::INT;
|
||||
|
||||
#[cfg(not(feature = "unchecked"))]
|
||||
use crate::{parser::Position, result::EvalAltResult, RegisterResultFn};
|
||||
|
||||
#[cfg(not(feature = "no_index"))]
|
||||
use crate::engine::Array;
|
||||
|
||||
#[cfg(not(feature = "no_float"))]
|
||||
use crate::FLOAT;
|
||||
|
||||
use std::{
|
||||
fmt::{Debug, Display},
|
||||
i32, i64,
|
||||
ops::{BitAnd, BitOr, BitXor, Range},
|
||||
u32,
|
||||
};
|
||||
|
||||
#[cfg(feature = "unchecked")]
|
||||
use std::ops::{Shl, Shr};
|
||||
|
||||
#[cfg(not(feature = "unchecked"))]
|
||||
#[cfg(not(feature = "no_float"))]
|
||||
use std::{i32, i64};
|
||||
|
||||
#[cfg(not(feature = "unchecked"))]
|
||||
#[cfg(not(feature = "only_i32"))]
|
||||
use std::u32;
|
||||
|
||||
#[cfg(any(feature = "unchecked", not(feature = "no_float")))]
|
||||
use std::ops::{Add, Div, Mul, Neg, Rem, Sub};
|
||||
|
||||
#[cfg(not(feature = "unchecked"))]
|
||||
use {
|
||||
crate::{parser::Position, result::EvalAltResult, RegisterResultFn},
|
||||
num_traits::{
|
||||
CheckedAdd, CheckedDiv, CheckedMul, CheckedNeg, CheckedRem, CheckedShl, CheckedShr,
|
||||
CheckedSub,
|
||||
@@ -259,7 +271,7 @@ impl Engine<'_> {
|
||||
x ^ y
|
||||
}
|
||||
#[cfg(not(feature = "unchecked"))]
|
||||
fn shl<T: Display + CheckedShl>(x: T, y: i64) -> Result<T, EvalAltResult> {
|
||||
fn shl<T: Display + CheckedShl>(x: T, y: INT) -> Result<T, EvalAltResult> {
|
||||
if y < 0 {
|
||||
return Err(EvalAltResult::ErrorArithmetic(
|
||||
format!("Left-shift by a negative number: {} << {}", x, y),
|
||||
@@ -275,7 +287,7 @@ impl Engine<'_> {
|
||||
})
|
||||
}
|
||||
#[cfg(not(feature = "unchecked"))]
|
||||
fn shr<T: Display + CheckedShr>(x: T, y: i64) -> Result<T, EvalAltResult> {
|
||||
fn shr<T: Display + CheckedShr>(x: T, y: INT) -> Result<T, EvalAltResult> {
|
||||
if y < 0 {
|
||||
return Err(EvalAltResult::ErrorArithmetic(
|
||||
format!("Right-shift by a negative number: {} >> {}", x, y),
|
||||
@@ -312,33 +324,58 @@ impl Engine<'_> {
|
||||
x % y
|
||||
}
|
||||
#[cfg(not(feature = "unchecked"))]
|
||||
fn pow_i64_i64_u(x: i64, y: i64) -> Result<i64, EvalAltResult> {
|
||||
if y > (u32::MAX as i64) {
|
||||
return Err(EvalAltResult::ErrorArithmetic(
|
||||
format!("Power overflow: {} ~ {}", x, y),
|
||||
Position::none(),
|
||||
));
|
||||
fn pow_i_i_u(x: INT, y: INT) -> Result<INT, EvalAltResult> {
|
||||
#[cfg(not(feature = "only_i32"))]
|
||||
{
|
||||
if y > (u32::MAX as INT) {
|
||||
Err(EvalAltResult::ErrorArithmetic(
|
||||
format!("Power overflow: {} ~ {}", x, y),
|
||||
Position::none(),
|
||||
))
|
||||
} else if y < 0 {
|
||||
Err(EvalAltResult::ErrorArithmetic(
|
||||
format!("Power underflow: {} ~ {}", x, y),
|
||||
Position::none(),
|
||||
))
|
||||
} else {
|
||||
x.checked_pow(y as u32).ok_or_else(|| {
|
||||
EvalAltResult::ErrorArithmetic(
|
||||
format!("Power overflow: {} ~ {}", x, y),
|
||||
Position::none(),
|
||||
)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
x.checked_pow(y as u32).ok_or_else(|| {
|
||||
EvalAltResult::ErrorArithmetic(
|
||||
format!("Power overflow: {} ~ {}", x, y),
|
||||
Position::none(),
|
||||
)
|
||||
})
|
||||
#[cfg(feature = "only_i32")]
|
||||
{
|
||||
if y < 0 {
|
||||
Err(EvalAltResult::ErrorArithmetic(
|
||||
format!("Power underflow: {} ~ {}", x, y),
|
||||
Position::none(),
|
||||
))
|
||||
} else {
|
||||
x.checked_pow(y as u32).ok_or_else(|| {
|
||||
EvalAltResult::ErrorArithmetic(
|
||||
format!("Power overflow: {} ~ {}", x, y),
|
||||
Position::none(),
|
||||
)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
#[cfg(feature = "unchecked")]
|
||||
fn pow_i64_i64(x: i64, y: i64) -> i64 {
|
||||
fn pow_i_i(x: INT, y: INT) -> INT {
|
||||
x.pow(y as u32)
|
||||
}
|
||||
#[cfg(not(feature = "no_float"))]
|
||||
fn pow_f64_f64(x: f64, y: f64) -> f64 {
|
||||
fn pow_f_f(x: FLOAT, y: FLOAT) -> FLOAT {
|
||||
x.powf(y)
|
||||
}
|
||||
#[cfg(not(feature = "unchecked"))]
|
||||
#[cfg(not(feature = "no_float"))]
|
||||
fn pow_f64_i64_u(x: f64, y: i64) -> Result<f64, EvalAltResult> {
|
||||
if y > (i32::MAX as i64) {
|
||||
fn pow_f_i_u(x: FLOAT, y: INT) -> Result<FLOAT, EvalAltResult> {
|
||||
if y > (i32::MAX as INT) {
|
||||
return Err(EvalAltResult::ErrorArithmetic(
|
||||
format!("Power overflow: {} ~ {}", x, y),
|
||||
Position::none(),
|
||||
@@ -349,24 +386,42 @@ impl Engine<'_> {
|
||||
}
|
||||
#[cfg(feature = "unchecked")]
|
||||
#[cfg(not(feature = "no_float"))]
|
||||
fn pow_f64_i64(x: f64, y: i64) -> f64 {
|
||||
fn pow_f_i(x: FLOAT, y: INT) -> FLOAT {
|
||||
x.powi(y as i32)
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "unchecked"))]
|
||||
{
|
||||
reg_op_result!(self, "+", add, i8, u8, i16, u16, i32, i64, u32, u64);
|
||||
reg_op_result!(self, "-", sub, i8, u8, i16, u16, i32, i64, u32, u64);
|
||||
reg_op_result!(self, "*", mul, i8, u8, i16, u16, i32, i64, u32, u64);
|
||||
reg_op_result!(self, "/", div, i8, u8, i16, u16, i32, i64, u32, u64);
|
||||
reg_op_result!(self, "+", add, INT);
|
||||
reg_op_result!(self, "-", sub, INT);
|
||||
reg_op_result!(self, "*", mul, INT);
|
||||
reg_op_result!(self, "/", div, INT);
|
||||
|
||||
#[cfg(not(feature = "only_i32"))]
|
||||
#[cfg(not(feature = "only_i64"))]
|
||||
{
|
||||
reg_op_result!(self, "+", add, i8, u8, i16, u16, i32, i64, u32, u64);
|
||||
reg_op_result!(self, "-", sub, i8, u8, i16, u16, i32, i64, u32, u64);
|
||||
reg_op_result!(self, "*", mul, i8, u8, i16, u16, i32, i64, u32, u64);
|
||||
reg_op_result!(self, "/", div, i8, u8, i16, u16, i32, i64, u32, u64);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "unchecked")]
|
||||
{
|
||||
reg_op!(self, "+", add_u, i8, u8, i16, u16, i32, i64, u32, u64);
|
||||
reg_op!(self, "-", sub_u, i8, u8, i16, u16, i32, i64, u32, u64);
|
||||
reg_op!(self, "*", mul_u, i8, u8, i16, u16, i32, i64, u32, u64);
|
||||
reg_op!(self, "/", div_u, i8, u8, i16, u16, i32, i64, u32, u64);
|
||||
reg_op!(self, "+", add_u, INT);
|
||||
reg_op!(self, "-", sub_u, INT);
|
||||
reg_op!(self, "*", mul_u, INT);
|
||||
reg_op!(self, "/", div_u, INT);
|
||||
|
||||
#[cfg(not(feature = "only_i32"))]
|
||||
#[cfg(not(feature = "only_i64"))]
|
||||
{
|
||||
reg_op!(self, "+", add_u, i8, u8, i16, u16, i32, i64, u32, u64);
|
||||
reg_op!(self, "-", sub_u, i8, u8, i16, u16, i32, i64, u32, u64);
|
||||
reg_op!(self, "*", mul_u, i8, u8, i16, u16, i32, i64, u32, u64);
|
||||
reg_op!(self, "/", div_u, i8, u8, i16, u16, i32, i64, u32, u64);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "no_float"))]
|
||||
@@ -377,12 +432,23 @@ impl Engine<'_> {
|
||||
reg_op!(self, "/", div_u, f32, f64);
|
||||
}
|
||||
|
||||
reg_cmp!(self, "<", lt, i8, u8, i16, u16, i32, i64, u32, u64, String, char);
|
||||
reg_cmp!(self, "<=", lte, i8, u8, i16, u16, i32, i64, u32, u64, String, char);
|
||||
reg_cmp!(self, ">", gt, i8, u8, i16, u16, i32, i64, u32, u64, String, char);
|
||||
reg_cmp!(self, ">=", gte, i8, u8, i16, u16, i32, i64, u32, u64, String, char);
|
||||
reg_cmp!(self, "==", eq, i8, u8, i16, u16, i32, i64, u32, u64, bool, String, char);
|
||||
reg_cmp!(self, "!=", ne, i8, u8, i16, u16, i32, i64, u32, u64, bool, String, char);
|
||||
reg_cmp!(self, "<", lt, INT, String, char);
|
||||
reg_cmp!(self, "<=", lte, INT, String, char);
|
||||
reg_cmp!(self, ">", gt, INT, String, char);
|
||||
reg_cmp!(self, ">=", gte, INT, String, char);
|
||||
reg_cmp!(self, "==", eq, INT, String, char, bool);
|
||||
reg_cmp!(self, "!=", ne, INT, String, char, bool);
|
||||
|
||||
#[cfg(not(feature = "only_i32"))]
|
||||
#[cfg(not(feature = "only_i64"))]
|
||||
{
|
||||
reg_cmp!(self, "<", lt, i8, u8, i16, u16, i32, i64, u32, u64);
|
||||
reg_cmp!(self, "<=", lte, i8, u8, i16, u16, i32, i64, u32, u64);
|
||||
reg_cmp!(self, ">", gt, i8, u8, i16, u16, i32, i64, u32, u64);
|
||||
reg_cmp!(self, ">=", gte, i8, u8, i16, u16, i32, i64, u32, u64);
|
||||
reg_cmp!(self, "==", eq, i8, u8, i16, u16, i32, i64, u32, u64);
|
||||
reg_cmp!(self, "!=", ne, i8, u8, i16, u16, i32, i64, u32, u64);
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "no_float"))]
|
||||
{
|
||||
@@ -396,60 +462,97 @@ impl Engine<'_> {
|
||||
|
||||
//reg_op!(self, "||", or, bool);
|
||||
//reg_op!(self, "&&", and, bool);
|
||||
reg_op!(self, "|", binary_or, i8, u8, i16, u16, i32, i64, u32, u64);
|
||||
reg_op!(self, "|", or, bool);
|
||||
reg_op!(self, "&", binary_and, i8, u8, i16, u16, i32, i64, u32, u64);
|
||||
reg_op!(self, "&", and, bool);
|
||||
reg_op!(self, "^", binary_xor, i8, u8, i16, u16, i32, i64, u32, u64);
|
||||
|
||||
reg_op!(self, "|", binary_or, INT);
|
||||
reg_op!(self, "&", binary_and, INT);
|
||||
reg_op!(self, "^", binary_xor, INT);
|
||||
|
||||
#[cfg(not(feature = "only_i32"))]
|
||||
#[cfg(not(feature = "only_i64"))]
|
||||
{
|
||||
reg_op!(self, "|", binary_or, i8, u8, i16, u16, i32, i64, u32, u64);
|
||||
reg_op!(self, "&", binary_and, i8, u8, i16, u16, i32, i64, u32, u64);
|
||||
reg_op!(self, "^", binary_xor, i8, u8, i16, u16, i32, i64, u32, u64);
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "unchecked"))]
|
||||
{
|
||||
reg_op_result1!(self, "<<", shl, i64, i8, u8, i16, u16, i32, i64, u32, u64);
|
||||
reg_op_result1!(self, ">>", shr, i64, i8, u8, i16, u16);
|
||||
reg_op_result1!(self, ">>", shr, i64, i32, i64, u32, u64);
|
||||
reg_op_result!(self, "%", modulo, i8, u8, i16, u16, i32, i64, u32, u64);
|
||||
reg_op_result1!(self, "<<", shl, INT, INT);
|
||||
reg_op_result1!(self, ">>", shr, INT, INT);
|
||||
reg_op_result!(self, "%", modulo, INT);
|
||||
|
||||
#[cfg(not(feature = "only_i32"))]
|
||||
#[cfg(not(feature = "only_i64"))]
|
||||
{
|
||||
reg_op_result1!(self, "<<", shl, i64, i8, u8, i16, u16, i32, i64, u32, u64);
|
||||
reg_op_result1!(self, ">>", shr, i64, i8, u8, i16, u16, i32, i64, u32, u64);
|
||||
reg_op_result!(self, "%", modulo, i8, u8, i16, u16, i32, i64, u32, u64);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "unchecked")]
|
||||
{
|
||||
reg_op!(self, "<<", shl_u, i64, i8, u8, i16, u16, i32, i64, u32, u64);
|
||||
reg_op!(self, ">>", shr_u, i64, i8, u8, i16, u16);
|
||||
reg_op!(self, ">>", shr_u, i64, i32, i64, u32, u64);
|
||||
reg_op!(self, "%", modulo_u, i8, u8, i16, u16, i32, i64, u32, u64);
|
||||
reg_op!(self, "<<", shl_u, INT, INT);
|
||||
reg_op!(self, ">>", shr_u, INT, INT);
|
||||
reg_op!(self, "%", modulo_u, INT);
|
||||
|
||||
#[cfg(not(feature = "only_i32"))]
|
||||
#[cfg(not(feature = "only_i64"))]
|
||||
{
|
||||
reg_op!(self, "<<", shl_u, i64, i8, u8, i16, u16, i32, i64, u32, u64);
|
||||
reg_op!(self, ">>", shr_u, i64, i8, u8, i16, u16, i32, i64, u32, u64);
|
||||
reg_op!(self, "%", modulo_u, i8, u8, i16, u16, i32, i64, u32, u64);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "no_float"))]
|
||||
{
|
||||
reg_op!(self, "%", modulo_u, f32, f64);
|
||||
self.register_fn("~", pow_f64_f64);
|
||||
self.register_fn("~", pow_f_f);
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "unchecked"))]
|
||||
{
|
||||
self.register_result_fn("~", pow_i64_i64_u);
|
||||
self.register_result_fn("~", pow_i_i_u);
|
||||
|
||||
#[cfg(not(feature = "no_float"))]
|
||||
self.register_result_fn("~", pow_f64_i64_u);
|
||||
self.register_result_fn("~", pow_f_i_u);
|
||||
}
|
||||
|
||||
#[cfg(feature = "unchecked")]
|
||||
{
|
||||
self.register_fn("~", pow_i64_i64);
|
||||
self.register_fn("~", pow_i_i);
|
||||
|
||||
#[cfg(not(feature = "no_float"))]
|
||||
self.register_fn("~", pow_f64_i64);
|
||||
self.register_fn("~", pow_f_i);
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "unchecked"))]
|
||||
{
|
||||
reg_un_result!(self, "-", neg, i8, i16, i32, i64);
|
||||
reg_un_result!(self, "abs", abs, i8, i16, i32, i64);
|
||||
reg_un_result!(self, "-", neg, INT);
|
||||
reg_un_result!(self, "abs", abs, INT);
|
||||
|
||||
#[cfg(not(feature = "only_i32"))]
|
||||
#[cfg(not(feature = "only_i64"))]
|
||||
{
|
||||
reg_un_result!(self, "-", neg, i8, i16, i32, i64);
|
||||
reg_un_result!(self, "abs", abs, i8, i16, i32, i64);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "unchecked")]
|
||||
{
|
||||
reg_un!(self, "-", neg_u, i8, i16, i32, i64);
|
||||
reg_un!(self, "abs", abs_u, i8, i16, i32, i64);
|
||||
reg_un!(self, "-", neg_u, INT);
|
||||
reg_un!(self, "abs", abs_u, INT);
|
||||
|
||||
#[cfg(not(feature = "only_i32"))]
|
||||
#[cfg(not(feature = "only_i64"))]
|
||||
{
|
||||
reg_un!(self, "-", neg_u, i8, i16, i32, i64);
|
||||
reg_un!(self, "abs", abs_u, i8, i16, i32, i64);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "no_float"))]
|
||||
@@ -464,33 +567,37 @@ impl Engine<'_> {
|
||||
self.register_fn("==", |_: (), _: ()| true); // () == ()
|
||||
|
||||
// Register print and debug
|
||||
fn print_debug<T: Debug>(x: T) -> String {
|
||||
fn debug<T: Debug>(x: T) -> String {
|
||||
format!("{:?}", x)
|
||||
}
|
||||
fn print<T: Display>(x: T) -> String {
|
||||
format!("{}", x)
|
||||
}
|
||||
|
||||
reg_func1!(self, "print", print, String, i8, u8, i16, u16);
|
||||
reg_func1!(self, "print", print, String, i32, i64, u32, u64);
|
||||
reg_func1!(self, "print", print, String, bool, char, String);
|
||||
reg_func1!(self, "print", print, String, INT, bool, char, String);
|
||||
self.register_fn("print", || "".to_string());
|
||||
self.register_fn("print", |_: ()| "".to_string());
|
||||
reg_func1!(self, "debug", debug, String, INT, bool, char, String, ());
|
||||
|
||||
reg_func1!(self, "debug", print_debug, String, i8, u8, i16, u16);
|
||||
reg_func1!(self, "debug", print_debug, String, i32, i64, u32, u64);
|
||||
reg_func1!(self, "debug", print_debug, String, bool, char, String, ());
|
||||
#[cfg(not(feature = "only_i32"))]
|
||||
#[cfg(not(feature = "only_i64"))]
|
||||
{
|
||||
reg_func1!(self, "print", print, String, i8, u8, i16, u16);
|
||||
reg_func1!(self, "print", print, String, i32, i64, u32, u64);
|
||||
reg_func1!(self, "debug", debug, String, i8, u8, i16, u16);
|
||||
reg_func1!(self, "debug", debug, String, i32, i64, u32, u64);
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "no_float"))]
|
||||
{
|
||||
reg_func1!(self, "print", print, String, f32, f64);
|
||||
reg_func1!(self, "debug", print_debug, String, f32, f64);
|
||||
reg_func1!(self, "debug", debug, String, f32, f64);
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "no_index"))]
|
||||
{
|
||||
reg_func1!(self, "print", print_debug, String, Array);
|
||||
reg_func1!(self, "debug", print_debug, String, Array);
|
||||
reg_func1!(self, "print", debug, String, Array);
|
||||
reg_func1!(self, "debug", debug, String, Array);
|
||||
|
||||
// Register array iterator
|
||||
self.register_iterator::<Array, _>(|a| {
|
||||
@@ -499,16 +606,16 @@ impl Engine<'_> {
|
||||
}
|
||||
|
||||
// Register range function
|
||||
self.register_iterator::<Range<i64>, _>(|a| {
|
||||
self.register_iterator::<Range<INT>, _>(|a| {
|
||||
Box::new(
|
||||
a.downcast_ref::<Range<i64>>()
|
||||
a.downcast_ref::<Range<INT>>()
|
||||
.unwrap()
|
||||
.clone()
|
||||
.map(|n| n.into_dynamic()),
|
||||
)
|
||||
});
|
||||
|
||||
self.register_fn("range", |i1: i64, i2: i64| (i1..i2));
|
||||
self.register_fn("range", |i1: INT, i2: INT| (i1..i2));
|
||||
}
|
||||
|
||||
/// Register the built-in library.
|
||||
@@ -520,52 +627,69 @@ impl Engine<'_> {
|
||||
#[cfg(not(feature = "no_float"))]
|
||||
{
|
||||
// Advanced math functions
|
||||
self.register_fn("sin", |x: f64| x.to_radians().sin());
|
||||
self.register_fn("cos", |x: f64| x.to_radians().cos());
|
||||
self.register_fn("tan", |x: f64| x.to_radians().tan());
|
||||
self.register_fn("sinh", |x: f64| x.to_radians().sinh());
|
||||
self.register_fn("cosh", |x: f64| x.to_radians().cosh());
|
||||
self.register_fn("tanh", |x: f64| x.to_radians().tanh());
|
||||
self.register_fn("asin", |x: f64| x.asin().to_degrees());
|
||||
self.register_fn("acos", |x: f64| x.acos().to_degrees());
|
||||
self.register_fn("atan", |x: f64| x.atan().to_degrees());
|
||||
self.register_fn("asinh", |x: f64| x.asinh().to_degrees());
|
||||
self.register_fn("acosh", |x: f64| x.acosh().to_degrees());
|
||||
self.register_fn("atanh", |x: f64| x.atanh().to_degrees());
|
||||
self.register_fn("sqrt", |x: f64| x.sqrt());
|
||||
self.register_fn("exp", |x: f64| x.exp());
|
||||
self.register_fn("ln", |x: f64| x.ln());
|
||||
self.register_fn("log", |x: f64, base: f64| x.log(base));
|
||||
self.register_fn("log10", |x: f64| x.log10());
|
||||
self.register_fn("floor", |x: f64| x.floor());
|
||||
self.register_fn("ceiling", |x: f64| x.ceil());
|
||||
self.register_fn("round", |x: f64| x.ceil());
|
||||
self.register_fn("int", |x: f64| x.trunc());
|
||||
self.register_fn("fraction", |x: f64| x.fract());
|
||||
self.register_fn("is_nan", |x: f64| x.is_nan());
|
||||
self.register_fn("is_finite", |x: f64| x.is_finite());
|
||||
self.register_fn("is_infinite", |x: f64| x.is_infinite());
|
||||
self.register_fn("sin", |x: FLOAT| x.to_radians().sin());
|
||||
self.register_fn("cos", |x: FLOAT| x.to_radians().cos());
|
||||
self.register_fn("tan", |x: FLOAT| x.to_radians().tan());
|
||||
self.register_fn("sinh", |x: FLOAT| x.to_radians().sinh());
|
||||
self.register_fn("cosh", |x: FLOAT| x.to_radians().cosh());
|
||||
self.register_fn("tanh", |x: FLOAT| x.to_radians().tanh());
|
||||
self.register_fn("asin", |x: FLOAT| x.asin().to_degrees());
|
||||
self.register_fn("acos", |x: FLOAT| x.acos().to_degrees());
|
||||
self.register_fn("atan", |x: FLOAT| x.atan().to_degrees());
|
||||
self.register_fn("asinh", |x: FLOAT| x.asinh().to_degrees());
|
||||
self.register_fn("acosh", |x: FLOAT| x.acosh().to_degrees());
|
||||
self.register_fn("atanh", |x: FLOAT| x.atanh().to_degrees());
|
||||
self.register_fn("sqrt", |x: FLOAT| x.sqrt());
|
||||
self.register_fn("exp", |x: FLOAT| x.exp());
|
||||
self.register_fn("ln", |x: FLOAT| x.ln());
|
||||
self.register_fn("log", |x: FLOAT, base: FLOAT| x.log(base));
|
||||
self.register_fn("log10", |x: FLOAT| x.log10());
|
||||
self.register_fn("floor", |x: FLOAT| x.floor());
|
||||
self.register_fn("ceiling", |x: FLOAT| x.ceil());
|
||||
self.register_fn("round", |x: FLOAT| x.ceil());
|
||||
self.register_fn("int", |x: FLOAT| x.trunc());
|
||||
self.register_fn("fraction", |x: FLOAT| x.fract());
|
||||
self.register_fn("is_nan", |x: FLOAT| x.is_nan());
|
||||
self.register_fn("is_finite", |x: FLOAT| x.is_finite());
|
||||
self.register_fn("is_infinite", |x: FLOAT| x.is_infinite());
|
||||
|
||||
// Register conversion functions
|
||||
self.register_fn("to_float", |x: i8| x as f64);
|
||||
self.register_fn("to_float", |x: u8| x as f64);
|
||||
self.register_fn("to_float", |x: i16| x as f64);
|
||||
self.register_fn("to_float", |x: u16| x as f64);
|
||||
self.register_fn("to_float", |x: i32| x as f64);
|
||||
self.register_fn("to_float", |x: u32| x as f64);
|
||||
self.register_fn("to_float", |x: i64| x as f64);
|
||||
self.register_fn("to_float", |x: u64| x as f64);
|
||||
self.register_fn("to_float", |x: f32| x as f64);
|
||||
self.register_fn("to_float", |x: INT| x as FLOAT);
|
||||
self.register_fn("to_float", |x: f32| x as FLOAT);
|
||||
|
||||
#[cfg(not(feature = "only_i32"))]
|
||||
#[cfg(not(feature = "only_i64"))]
|
||||
{
|
||||
self.register_fn("to_float", |x: i8| x as FLOAT);
|
||||
self.register_fn("to_float", |x: u8| x as FLOAT);
|
||||
self.register_fn("to_float", |x: i16| x as FLOAT);
|
||||
self.register_fn("to_float", |x: u16| x as FLOAT);
|
||||
self.register_fn("to_float", |x: i32| x as FLOAT);
|
||||
self.register_fn("to_float", |x: u32| x as FLOAT);
|
||||
self.register_fn("to_float", |x: i64| x as FLOAT);
|
||||
self.register_fn("to_float", |x: u64| x as FLOAT);
|
||||
}
|
||||
}
|
||||
|
||||
self.register_fn("to_int", |x: i8| x as i64);
|
||||
self.register_fn("to_int", |x: u8| x as i64);
|
||||
self.register_fn("to_int", |x: i16| x as i64);
|
||||
self.register_fn("to_int", |x: u16| x as i64);
|
||||
self.register_fn("to_int", |x: i32| x as i64);
|
||||
self.register_fn("to_int", |x: u32| x as i64);
|
||||
self.register_fn("to_int", |x: u64| x as i64);
|
||||
self.register_fn("to_int", |ch: char| ch as i64);
|
||||
self.register_fn("to_int", |ch: char| ch as INT);
|
||||
|
||||
#[cfg(not(feature = "only_i32"))]
|
||||
#[cfg(not(feature = "only_i64"))]
|
||||
{
|
||||
self.register_fn("to_int", |x: i8| x as INT);
|
||||
self.register_fn("to_int", |x: u8| x as INT);
|
||||
self.register_fn("to_int", |x: i16| x as INT);
|
||||
self.register_fn("to_int", |x: u16| x as INT);
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "only_i32"))]
|
||||
{
|
||||
self.register_fn("to_int", |x: i32| x as INT);
|
||||
self.register_fn("to_int", |x: u64| x as INT);
|
||||
|
||||
#[cfg(feature = "only_i64")]
|
||||
self.register_fn("to_int", |x: u32| x as INT);
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "no_float"))]
|
||||
{
|
||||
@@ -579,24 +703,24 @@ impl Engine<'_> {
|
||||
));
|
||||
}
|
||||
|
||||
Ok(x.trunc() as i64)
|
||||
Ok(x.trunc() as INT)
|
||||
});
|
||||
self.register_result_fn("to_int", |x: f64| {
|
||||
if x > (i64::MAX as f64) {
|
||||
self.register_result_fn("to_int", |x: FLOAT| {
|
||||
if x > (i64::MAX as FLOAT) {
|
||||
return Err(EvalAltResult::ErrorArithmetic(
|
||||
format!("Integer overflow: to_int({})", x),
|
||||
Position::none(),
|
||||
));
|
||||
}
|
||||
|
||||
Ok(x.trunc() as i64)
|
||||
Ok(x.trunc() as INT)
|
||||
});
|
||||
}
|
||||
|
||||
#[cfg(feature = "unchecked")]
|
||||
{
|
||||
self.register_fn("to_int", |x: f32| x as i64);
|
||||
self.register_fn("to_int", |x: f64| x as i64);
|
||||
self.register_fn("to_int", |x: f32| x as INT);
|
||||
self.register_fn("to_int", |x: f64| x as INT);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -606,7 +730,7 @@ impl Engine<'_> {
|
||||
fn push<T: Any>(list: &mut Array, item: T) {
|
||||
list.push(Box::new(item));
|
||||
}
|
||||
fn pad<T: Any + Clone>(list: &mut Array, len: i64, item: T) {
|
||||
fn pad<T: Any + Clone>(list: &mut Array, len: INT, item: T) {
|
||||
if len >= 0 {
|
||||
while list.len() < len as usize {
|
||||
push(list, item.clone());
|
||||
@@ -614,19 +738,24 @@ impl Engine<'_> {
|
||||
}
|
||||
}
|
||||
|
||||
reg_func2x!(self, "push", push, &mut Array, (), i8, u8, i16, u16);
|
||||
reg_func2x!(self, "push", push, &mut Array, (), i32, i64, u32, u64);
|
||||
reg_func2x!(self, "push", push, &mut Array, (), bool, char);
|
||||
reg_func2x!(self, "push", push, &mut Array, (), INT, bool, char);
|
||||
reg_func2x!(self, "push", push, &mut Array, (), String, Array, ());
|
||||
reg_func3!(self, "pad", pad, &mut Array, i64, (), i8, u8, i16, u16);
|
||||
reg_func3!(self, "pad", pad, &mut Array, i64, (), i32, u32, i64, u64);
|
||||
reg_func3!(self, "pad", pad, &mut Array, i64, (), bool, char);
|
||||
reg_func3!(self, "pad", pad, &mut Array, i64, (), String, Array, ());
|
||||
reg_func3!(self, "pad", pad, &mut Array, INT, (), INT, bool, char);
|
||||
reg_func3!(self, "pad", pad, &mut Array, INT, (), String, Array, ());
|
||||
|
||||
#[cfg(not(feature = "only_i32"))]
|
||||
#[cfg(not(feature = "only_i64"))]
|
||||
{
|
||||
reg_func2x!(self, "push", push, &mut Array, (), i8, u8, i16, u16);
|
||||
reg_func2x!(self, "push", push, &mut Array, (), i32, i64, u32, u64);
|
||||
reg_func3!(self, "pad", pad, &mut Array, INT, (), i8, u8, i16, u16);
|
||||
reg_func3!(self, "pad", pad, &mut Array, INT, (), i32, u32, i64, u64);
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "no_float"))]
|
||||
{
|
||||
reg_func2x!(self, "push", push, &mut Array, (), f32, f64);
|
||||
reg_func3!(self, "pad", pad, &mut Array, i64, (), f32, f64);
|
||||
reg_func3!(self, "pad", pad, &mut Array, INT, (), f32, f64);
|
||||
}
|
||||
|
||||
self.register_dynamic_fn("pop", |list: &mut Array| {
|
||||
@@ -636,9 +765,9 @@ impl Engine<'_> {
|
||||
0 => ().into_dynamic(),
|
||||
_ => list.remove(0),
|
||||
});
|
||||
self.register_fn("len", |list: &mut Array| list.len() as i64);
|
||||
self.register_fn("len", |list: &mut Array| list.len() as INT);
|
||||
self.register_fn("clear", |list: &mut Array| list.clear());
|
||||
self.register_fn("truncate", |list: &mut Array, len: i64| {
|
||||
self.register_fn("truncate", |list: &mut Array, len: INT| {
|
||||
if len >= 0 {
|
||||
list.truncate(len as usize);
|
||||
}
|
||||
@@ -653,16 +782,19 @@ impl Engine<'_> {
|
||||
format!("{}{}", x, y)
|
||||
}
|
||||
|
||||
reg_func2x!(
|
||||
self, "+", append, String, String, i8, u8, i16, u16, i32, i64, u32, u64, bool, char
|
||||
);
|
||||
reg_func2x!(self, "+", append, String, String, INT, bool, char);
|
||||
self.register_fn("+", |x: String, _: ()| format!("{}", x));
|
||||
|
||||
reg_func2y!(
|
||||
self, "+", prepend, String, String, i8, u8, i16, u16, i32, i64, u32, u64, bool, char
|
||||
);
|
||||
reg_func2y!(self, "+", prepend, String, String, INT, bool, char);
|
||||
self.register_fn("+", |_: (), y: String| format!("{}", y));
|
||||
|
||||
#[cfg(not(feature = "only_i32"))]
|
||||
#[cfg(not(feature = "only_i64"))]
|
||||
{
|
||||
reg_func2x!(self, "+", append, String, String, i8, u8, i16, u16, i32, i64, u32, u64);
|
||||
reg_func2y!(self, "+", prepend, String, String, i8, u8, i16, u16, i32, i64, u32, u64);
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "no_float"))]
|
||||
{
|
||||
reg_func2x!(self, "+", append, String, String, f32, f64);
|
||||
@@ -676,13 +808,13 @@ impl Engine<'_> {
|
||||
}
|
||||
|
||||
// Register string utility functions
|
||||
self.register_fn("len", |s: &mut String| s.chars().count() as i64);
|
||||
self.register_fn("len", |s: &mut String| s.chars().count() as INT);
|
||||
self.register_fn("contains", |s: &mut String, ch: char| s.contains(ch));
|
||||
self.register_fn("contains", |s: &mut String, find: String| s.contains(&find));
|
||||
self.register_fn("clear", |s: &mut String| s.clear());
|
||||
self.register_fn("append", |s: &mut String, ch: char| s.push(ch));
|
||||
self.register_fn("append", |s: &mut String, add: String| s.push_str(&add));
|
||||
self.register_fn("truncate", |s: &mut String, len: i64| {
|
||||
self.register_fn("truncate", |s: &mut String, len: INT| {
|
||||
if len >= 0 {
|
||||
let chars: Vec<_> = s.chars().take(len as usize).collect();
|
||||
s.clear();
|
||||
@@ -691,7 +823,7 @@ impl Engine<'_> {
|
||||
s.clear();
|
||||
}
|
||||
});
|
||||
self.register_fn("pad", |s: &mut String, len: i64, ch: char| {
|
||||
self.register_fn("pad", |s: &mut String, len: INT, ch: char| {
|
||||
for _ in 0..s.chars().count() - len as usize {
|
||||
s.push(ch);
|
||||
}
|
||||
|
Reference in New Issue
Block a user