Code style refactor.
This commit is contained in:
parent
58d6a88bc4
commit
dfea3ed22a
15
src/ast.rs
15
src/ast.rs
@ -253,12 +253,11 @@ impl AST {
|
|||||||
/// Set the source.
|
/// Set the source.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn set_source(&mut self, source: impl Into<Identifier>) -> &mut Self {
|
pub fn set_source(&mut self, source: impl Into<Identifier>) -> &mut Self {
|
||||||
self.source = Some(source.into());
|
let source = Some(source.into());
|
||||||
|
Shared::get_mut(&mut self.functions)
|
||||||
if let Some(module) = Shared::get_mut(&mut self.functions) {
|
.as_mut()
|
||||||
module.set_id(self.source.clone());
|
.map(|m| m.set_id(source.clone()));
|
||||||
}
|
self.source = source;
|
||||||
|
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
/// Clear the source.
|
/// Clear the source.
|
||||||
@ -1791,9 +1790,7 @@ impl fmt::Debug for Expr {
|
|||||||
}
|
}
|
||||||
Self::FnCall(x, _) => {
|
Self::FnCall(x, _) => {
|
||||||
let mut ff = f.debug_struct("FnCall");
|
let mut ff = f.debug_struct("FnCall");
|
||||||
if let Some(ref ns) = x.namespace {
|
x.namespace.as_ref().map(|ns| ff.field("namespace", ns));
|
||||||
ff.field("namespace", ns);
|
|
||||||
}
|
|
||||||
ff.field("name", &x.name)
|
ff.field("name", &x.name)
|
||||||
.field("hash", &x.hashes)
|
.field("hash", &x.hashes)
|
||||||
.field("args", &x.args);
|
.field("args", &x.args);
|
||||||
|
281
src/dynamic.rs
281
src/dynamic.rs
@ -240,7 +240,6 @@ impl<'d, T: Any + Clone> Deref for DynamicReadLock<'d, T> {
|
|||||||
fn deref(&self) -> &Self::Target {
|
fn deref(&self) -> &Self::Target {
|
||||||
match &self.0 {
|
match &self.0 {
|
||||||
DynamicReadLockInner::Reference(reference) => *reference,
|
DynamicReadLockInner::Reference(reference) => *reference,
|
||||||
// Unwrapping is safe because all checking is already done in its constructor
|
|
||||||
#[cfg(not(feature = "no_closure"))]
|
#[cfg(not(feature = "no_closure"))]
|
||||||
DynamicReadLockInner::Guard(guard) => guard.downcast_ref().expect(
|
DynamicReadLockInner::Guard(guard) => guard.downcast_ref().expect(
|
||||||
"never fails because the read guard was created after checking the data type",
|
"never fails because the read guard was created after checking the data type",
|
||||||
@ -284,10 +283,9 @@ impl<'d, T: Any + Clone> Deref for DynamicWriteLock<'d, T> {
|
|||||||
fn deref(&self) -> &Self::Target {
|
fn deref(&self) -> &Self::Target {
|
||||||
match &self.0 {
|
match &self.0 {
|
||||||
DynamicWriteLockInner::Reference(reference) => *reference,
|
DynamicWriteLockInner::Reference(reference) => *reference,
|
||||||
// Unwrapping is safe because all checking is already done in its constructor
|
|
||||||
#[cfg(not(feature = "no_closure"))]
|
#[cfg(not(feature = "no_closure"))]
|
||||||
DynamicWriteLockInner::Guard(guard) => guard.downcast_ref().expect(
|
DynamicWriteLockInner::Guard(guard) => guard.downcast_ref().expect(
|
||||||
"never fails because the read guard was created after checking the data type",
|
"never fails because the write guard was created after checking the data type",
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -298,7 +296,6 @@ impl<'d, T: Any + Clone> DerefMut for DynamicWriteLock<'d, T> {
|
|||||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||||
match &mut self.0 {
|
match &mut self.0 {
|
||||||
DynamicWriteLockInner::Reference(reference) => *reference,
|
DynamicWriteLockInner::Reference(reference) => *reference,
|
||||||
// Unwrapping is safe because all checking is already done in its constructor
|
|
||||||
#[cfg(not(feature = "no_closure"))]
|
#[cfg(not(feature = "no_closure"))]
|
||||||
DynamicWriteLockInner::Guard(guard) => guard.downcast_mut().expect(
|
DynamicWriteLockInner::Guard(guard) => guard.downcast_mut().expect(
|
||||||
"never fails because the write guard was created after checking the data type",
|
"never fails because the write guard was created after checking the data type",
|
||||||
@ -309,7 +306,7 @@ impl<'d, T: Any + Clone> DerefMut for DynamicWriteLock<'d, T> {
|
|||||||
|
|
||||||
impl Dynamic {
|
impl Dynamic {
|
||||||
/// Get the arbitrary data attached to this [`Dynamic`].
|
/// Get the arbitrary data attached to this [`Dynamic`].
|
||||||
pub fn tag(&self) -> Tag {
|
pub const fn tag(&self) -> Tag {
|
||||||
match self.0 {
|
match self.0 {
|
||||||
Union::Unit(_, tag, _)
|
Union::Unit(_, tag, _)
|
||||||
| Union::Bool(_, tag, _)
|
| Union::Bool(_, tag, _)
|
||||||
@ -361,7 +358,7 @@ impl Dynamic {
|
|||||||
/// Does this [`Dynamic`] hold a variant data type
|
/// Does this [`Dynamic`] hold a variant data type
|
||||||
/// instead of one of the supported system primitive types?
|
/// instead of one of the supported system primitive types?
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn is_variant(&self) -> bool {
|
pub const fn is_variant(&self) -> bool {
|
||||||
match self.0 {
|
match self.0 {
|
||||||
Union::Variant(_, _, _) => true,
|
Union::Variant(_, _, _) => true,
|
||||||
_ => false,
|
_ => false,
|
||||||
@ -372,7 +369,7 @@ impl Dynamic {
|
|||||||
/// Not available under `no_closure`.
|
/// Not available under `no_closure`.
|
||||||
#[cfg(not(feature = "no_closure"))]
|
#[cfg(not(feature = "no_closure"))]
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn is_shared(&self) -> bool {
|
pub const fn is_shared(&self) -> bool {
|
||||||
#[cfg(not(feature = "no_closure"))]
|
#[cfg(not(feature = "no_closure"))]
|
||||||
match self.0 {
|
match self.0 {
|
||||||
Union::Shared(_, _, _) => return true,
|
Union::Shared(_, _, _) => return true,
|
||||||
@ -420,7 +417,7 @@ impl Dynamic {
|
|||||||
#[cfg(not(feature = "no_std"))]
|
#[cfg(not(feature = "no_std"))]
|
||||||
Union::TimeStamp(_, _, _) => TypeId::of::<Instant>(),
|
Union::TimeStamp(_, _, _) => TypeId::of::<Instant>(),
|
||||||
|
|
||||||
Union::Variant(value, _, _) => (***value).type_id(),
|
Union::Variant(value, _, _) => value.as_ref().as_ref().type_id(),
|
||||||
|
|
||||||
#[cfg(not(feature = "no_closure"))]
|
#[cfg(not(feature = "no_closure"))]
|
||||||
Union::Shared(cell, _, _) => {
|
Union::Shared(cell, _, _) => {
|
||||||
@ -458,7 +455,7 @@ impl Dynamic {
|
|||||||
#[cfg(not(feature = "no_std"))]
|
#[cfg(not(feature = "no_std"))]
|
||||||
Union::TimeStamp(_, _, _) => "timestamp",
|
Union::TimeStamp(_, _, _) => "timestamp",
|
||||||
|
|
||||||
Union::Variant(value, _, _) => (***value).type_name(),
|
Union::Variant(value, _, _) => value.as_ref().as_ref().type_name(),
|
||||||
|
|
||||||
#[cfg(not(feature = "no_closure"))]
|
#[cfg(not(feature = "no_closure"))]
|
||||||
#[cfg(not(feature = "sync"))]
|
#[cfg(not(feature = "sync"))]
|
||||||
@ -484,17 +481,12 @@ impl Hash for Dynamic {
|
|||||||
#[cfg(not(feature = "no_float"))]
|
#[cfg(not(feature = "no_float"))]
|
||||||
Union::Float(f, _, _) => f.hash(state),
|
Union::Float(f, _, _) => f.hash(state),
|
||||||
#[cfg(not(feature = "no_index"))]
|
#[cfg(not(feature = "no_index"))]
|
||||||
Union::Array(a, _, _) => (**a).hash(state),
|
Union::Array(a, _, _) => a.as_ref().hash(state),
|
||||||
#[cfg(not(feature = "no_object"))]
|
#[cfg(not(feature = "no_object"))]
|
||||||
Union::Map(m, _, _) => {
|
Union::Map(m, _, _) => m.iter().for_each(|(key, value)| {
|
||||||
let mut buf: crate::StaticVec<_> = m.iter().collect();
|
key.hash(state);
|
||||||
buf.sort_by(|(a, _), (b, _)| a.cmp(b));
|
value.hash(state);
|
||||||
|
}),
|
||||||
buf.into_iter().for_each(|(key, value)| {
|
|
||||||
key.hash(state);
|
|
||||||
value.hash(state);
|
|
||||||
})
|
|
||||||
}
|
|
||||||
Union::FnPtr(f, _, _) if f.is_curried() => {
|
Union::FnPtr(f, _, _) if f.is_curried() => {
|
||||||
unimplemented!(
|
unimplemented!(
|
||||||
"{} with curried arguments cannot be hashed",
|
"{} with curried arguments cannot be hashed",
|
||||||
@ -577,93 +569,47 @@ impl fmt::Display for Dynamic {
|
|||||||
Union::TimeStamp(_, _, _) => f.write_str("<timestamp>"),
|
Union::TimeStamp(_, _, _) => f.write_str("<timestamp>"),
|
||||||
|
|
||||||
Union::Variant(value, _, _) => {
|
Union::Variant(value, _, _) => {
|
||||||
let _type_id = (***value).type_id();
|
let value = value.as_ref().as_ref();
|
||||||
|
let _type_id = value.type_id();
|
||||||
|
let _value_any = value.as_any();
|
||||||
|
|
||||||
const CHECKED: &str = "never fails because the type was checked";
|
const CHECKED: &str = "never fails because the type was checked";
|
||||||
|
|
||||||
#[cfg(not(feature = "only_i32"))]
|
#[cfg(not(feature = "only_i32"))]
|
||||||
#[cfg(not(feature = "only_i64"))]
|
#[cfg(not(feature = "only_i64"))]
|
||||||
if _type_id == TypeId::of::<u8>() {
|
if _type_id == TypeId::of::<u8>() {
|
||||||
return write!(
|
return fmt::Display::fmt(_value_any.downcast_ref::<u8>().expect(CHECKED), f);
|
||||||
f,
|
|
||||||
"{}",
|
|
||||||
(**value).as_any().downcast_ref::<u8>().expect(CHECKED),
|
|
||||||
);
|
|
||||||
} else if _type_id == TypeId::of::<u16>() {
|
} else if _type_id == TypeId::of::<u16>() {
|
||||||
return write!(
|
return fmt::Display::fmt(_value_any.downcast_ref::<u16>().expect(CHECKED), f);
|
||||||
f,
|
|
||||||
"{}",
|
|
||||||
(**value).as_any().downcast_ref::<u16>().expect(CHECKED)
|
|
||||||
);
|
|
||||||
} else if _type_id == TypeId::of::<u32>() {
|
} else if _type_id == TypeId::of::<u32>() {
|
||||||
return write!(
|
return fmt::Display::fmt(_value_any.downcast_ref::<u32>().expect(CHECKED), f);
|
||||||
f,
|
|
||||||
"{}",
|
|
||||||
(**value).as_any().downcast_ref::<u32>().expect(CHECKED)
|
|
||||||
);
|
|
||||||
} else if _type_id == TypeId::of::<u64>() {
|
} else if _type_id == TypeId::of::<u64>() {
|
||||||
return write!(
|
return fmt::Display::fmt(_value_any.downcast_ref::<u64>().expect(CHECKED), f);
|
||||||
f,
|
|
||||||
"{}",
|
|
||||||
(**value).as_any().downcast_ref::<u64>().expect(CHECKED)
|
|
||||||
);
|
|
||||||
} else if _type_id == TypeId::of::<i8>() {
|
} else if _type_id == TypeId::of::<i8>() {
|
||||||
return write!(
|
return fmt::Display::fmt(_value_any.downcast_ref::<i8>().expect(CHECKED), f);
|
||||||
f,
|
|
||||||
"{}",
|
|
||||||
(**value).as_any().downcast_ref::<i8>().expect(CHECKED)
|
|
||||||
);
|
|
||||||
} else if _type_id == TypeId::of::<i16>() {
|
} else if _type_id == TypeId::of::<i16>() {
|
||||||
return write!(
|
return fmt::Display::fmt(_value_any.downcast_ref::<i16>().expect(CHECKED), f);
|
||||||
f,
|
|
||||||
"{}",
|
|
||||||
(**value).as_any().downcast_ref::<i16>().expect(CHECKED)
|
|
||||||
);
|
|
||||||
} else if _type_id == TypeId::of::<i32>() {
|
} else if _type_id == TypeId::of::<i32>() {
|
||||||
return write!(
|
return fmt::Display::fmt(_value_any.downcast_ref::<i32>().expect(CHECKED), f);
|
||||||
f,
|
|
||||||
"{}",
|
|
||||||
(**value).as_any().downcast_ref::<i32>().expect(CHECKED)
|
|
||||||
);
|
|
||||||
} else if _type_id == TypeId::of::<i64>() {
|
} else if _type_id == TypeId::of::<i64>() {
|
||||||
return write!(
|
return fmt::Display::fmt(_value_any.downcast_ref::<i64>().expect(CHECKED), f);
|
||||||
f,
|
|
||||||
"{}",
|
|
||||||
(**value).as_any().downcast_ref::<i64>().expect(CHECKED)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "no_float"))]
|
#[cfg(not(feature = "no_float"))]
|
||||||
if _type_id == TypeId::of::<f32>() {
|
if _type_id == TypeId::of::<f32>() {
|
||||||
return write!(
|
return fmt::Display::fmt(_value_any.downcast_ref::<f32>().expect(CHECKED), f);
|
||||||
f,
|
|
||||||
"{}",
|
|
||||||
(**value).as_any().downcast_ref::<f32>().expect(CHECKED)
|
|
||||||
);
|
|
||||||
} else if _type_id == TypeId::of::<f64>() {
|
} else if _type_id == TypeId::of::<f64>() {
|
||||||
return write!(
|
return fmt::Display::fmt(_value_any.downcast_ref::<f64>().expect(CHECKED), f);
|
||||||
f,
|
|
||||||
"{}",
|
|
||||||
(**value).as_any().downcast_ref::<f64>().expect(CHECKED)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(any(target_arch = "wasm32", target_arch = "wasm64")))]
|
#[cfg(not(any(target_arch = "wasm32", target_arch = "wasm64")))]
|
||||||
if _type_id == TypeId::of::<u128>() {
|
if _type_id == TypeId::of::<u128>() {
|
||||||
return write!(
|
return fmt::Display::fmt(_value_any.downcast_ref::<u128>().expect(CHECKED), f);
|
||||||
f,
|
|
||||||
"{}",
|
|
||||||
(**value).as_any().downcast_ref::<u128>().expect(CHECKED)
|
|
||||||
);
|
|
||||||
} else if _type_id == TypeId::of::<i128>() {
|
} else if _type_id == TypeId::of::<i128>() {
|
||||||
return write!(
|
return fmt::Display::fmt(_value_any.downcast_ref::<i128>().expect(CHECKED), f);
|
||||||
f,
|
|
||||||
"{}",
|
|
||||||
(**value).as_any().downcast_ref::<i128>().expect(CHECKED)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
f.write_str((***value).type_name())
|
f.write_str(value.type_name())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "no_closure"))]
|
#[cfg(not(feature = "no_closure"))]
|
||||||
@ -706,93 +652,47 @@ impl fmt::Debug for Dynamic {
|
|||||||
Union::TimeStamp(_, _, _) => write!(f, "<timestamp>"),
|
Union::TimeStamp(_, _, _) => write!(f, "<timestamp>"),
|
||||||
|
|
||||||
Union::Variant(value, _, _) => {
|
Union::Variant(value, _, _) => {
|
||||||
let _type_id = (***value).type_id();
|
let value = value.as_ref().as_ref();
|
||||||
|
let _type_id = value.type_id();
|
||||||
|
let _value_any = value.as_any();
|
||||||
|
|
||||||
const CHECKED: &str = "never fails because the type was checked";
|
const CHECKED: &str = "never fails because the type was checked";
|
||||||
|
|
||||||
#[cfg(not(feature = "only_i32"))]
|
#[cfg(not(feature = "only_i32"))]
|
||||||
#[cfg(not(feature = "only_i64"))]
|
#[cfg(not(feature = "only_i64"))]
|
||||||
if _type_id == TypeId::of::<u8>() {
|
if _type_id == TypeId::of::<u8>() {
|
||||||
return write!(
|
return fmt::Debug::fmt(_value_any.downcast_ref::<u8>().expect(CHECKED), f);
|
||||||
f,
|
|
||||||
"{:?}",
|
|
||||||
(**value).as_any().downcast_ref::<u8>().expect(CHECKED)
|
|
||||||
);
|
|
||||||
} else if _type_id == TypeId::of::<u16>() {
|
} else if _type_id == TypeId::of::<u16>() {
|
||||||
return write!(
|
return fmt::Debug::fmt(_value_any.downcast_ref::<u16>().expect(CHECKED), f);
|
||||||
f,
|
|
||||||
"{:?}",
|
|
||||||
(**value).as_any().downcast_ref::<u16>().expect(CHECKED)
|
|
||||||
);
|
|
||||||
} else if _type_id == TypeId::of::<u32>() {
|
} else if _type_id == TypeId::of::<u32>() {
|
||||||
return write!(
|
return fmt::Debug::fmt(_value_any.downcast_ref::<u32>().expect(CHECKED), f);
|
||||||
f,
|
|
||||||
"{:?}",
|
|
||||||
(**value).as_any().downcast_ref::<u32>().expect(CHECKED)
|
|
||||||
);
|
|
||||||
} else if _type_id == TypeId::of::<u64>() {
|
} else if _type_id == TypeId::of::<u64>() {
|
||||||
return write!(
|
return fmt::Debug::fmt(_value_any.downcast_ref::<u64>().expect(CHECKED), f);
|
||||||
f,
|
|
||||||
"{:?}",
|
|
||||||
(**value).as_any().downcast_ref::<u64>().expect(CHECKED)
|
|
||||||
);
|
|
||||||
} else if _type_id == TypeId::of::<i8>() {
|
} else if _type_id == TypeId::of::<i8>() {
|
||||||
return write!(
|
return fmt::Debug::fmt(_value_any.downcast_ref::<i8>().expect(CHECKED), f);
|
||||||
f,
|
|
||||||
"{:?}",
|
|
||||||
(**value).as_any().downcast_ref::<i8>().expect(CHECKED)
|
|
||||||
);
|
|
||||||
} else if _type_id == TypeId::of::<i16>() {
|
} else if _type_id == TypeId::of::<i16>() {
|
||||||
return write!(
|
return fmt::Debug::fmt(_value_any.downcast_ref::<i16>().expect(CHECKED), f);
|
||||||
f,
|
|
||||||
"{:?}",
|
|
||||||
(**value).as_any().downcast_ref::<i16>().expect(CHECKED)
|
|
||||||
);
|
|
||||||
} else if _type_id == TypeId::of::<i32>() {
|
} else if _type_id == TypeId::of::<i32>() {
|
||||||
return write!(
|
return fmt::Debug::fmt(_value_any.downcast_ref::<i32>().expect(CHECKED), f);
|
||||||
f,
|
|
||||||
"{:?}",
|
|
||||||
(**value).as_any().downcast_ref::<i32>().expect(CHECKED)
|
|
||||||
);
|
|
||||||
} else if _type_id == TypeId::of::<i64>() {
|
} else if _type_id == TypeId::of::<i64>() {
|
||||||
return write!(
|
return fmt::Debug::fmt(_value_any.downcast_ref::<i64>().expect(CHECKED), f);
|
||||||
f,
|
|
||||||
"{:?}",
|
|
||||||
(**value).as_any().downcast_ref::<i64>().expect(CHECKED)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "no_float"))]
|
#[cfg(not(feature = "no_float"))]
|
||||||
if _type_id == TypeId::of::<f32>() {
|
if _type_id == TypeId::of::<f32>() {
|
||||||
return write!(
|
return fmt::Debug::fmt(_value_any.downcast_ref::<f32>().expect(CHECKED), f);
|
||||||
f,
|
|
||||||
"{}",
|
|
||||||
(**value).as_any().downcast_ref::<f32>().expect(CHECKED)
|
|
||||||
);
|
|
||||||
} else if _type_id == TypeId::of::<f64>() {
|
} else if _type_id == TypeId::of::<f64>() {
|
||||||
return write!(
|
return fmt::Debug::fmt(_value_any.downcast_ref::<f64>().expect(CHECKED), f);
|
||||||
f,
|
|
||||||
"{}",
|
|
||||||
(**value).as_any().downcast_ref::<f64>().expect(CHECKED)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(any(target_arch = "wasm32", target_arch = "wasm64")))]
|
#[cfg(not(any(target_arch = "wasm32", target_arch = "wasm64")))]
|
||||||
if _type_id == TypeId::of::<u128>() {
|
if _type_id == TypeId::of::<u128>() {
|
||||||
return write!(
|
return fmt::Debug::fmt(_value_any.downcast_ref::<u128>().expect(CHECKED), f);
|
||||||
f,
|
|
||||||
"{:?}",
|
|
||||||
(**value).as_any().downcast_ref::<u128>().expect(CHECKED)
|
|
||||||
);
|
|
||||||
} else if _type_id == TypeId::of::<i128>() {
|
} else if _type_id == TypeId::of::<i128>() {
|
||||||
return write!(
|
return fmt::Debug::fmt(_value_any.downcast_ref::<i128>().expect(CHECKED), f);
|
||||||
f,
|
|
||||||
"{:?}",
|
|
||||||
(**value).as_any().downcast_ref::<i128>().expect(CHECKED)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
write!(f, "{}", (*value).type_name())
|
write!(f, "{}", value.type_name())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "no_closure"))]
|
#[cfg(not(feature = "no_closure"))]
|
||||||
@ -849,7 +749,7 @@ impl Clone for Dynamic {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Union::Variant(ref value, tag, _) => {
|
Union::Variant(ref value, tag, _) => {
|
||||||
let mut x = (***value).clone_into_dynamic();
|
let mut x = value.as_ref().as_ref().clone_into_dynamic();
|
||||||
x.set_tag(tag);
|
x.set_tag(tag);
|
||||||
x
|
x
|
||||||
}
|
}
|
||||||
@ -933,7 +833,7 @@ impl Dynamic {
|
|||||||
));
|
));
|
||||||
|
|
||||||
/// Get the [`AccessMode`] for this [`Dynamic`].
|
/// Get the [`AccessMode`] for this [`Dynamic`].
|
||||||
pub(crate) fn access_mode(&self) -> AccessMode {
|
pub(crate) const fn access_mode(&self) -> AccessMode {
|
||||||
match self.0 {
|
match self.0 {
|
||||||
Union::Unit(_, _, access)
|
Union::Unit(_, _, access)
|
||||||
| Union::Bool(_, _, access)
|
| Union::Bool(_, _, access)
|
||||||
@ -1089,49 +989,34 @@ impl Dynamic {
|
|||||||
return unsafe_try_cast::<_, Dynamic>(value).ok().expect(CHECKED);
|
return unsafe_try_cast::<_, Dynamic>(value).ok().expect(CHECKED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let val = value.as_any();
|
||||||
|
|
||||||
if TypeId::of::<T>() == TypeId::of::<INT>() {
|
if TypeId::of::<T>() == TypeId::of::<INT>() {
|
||||||
return <dyn Any>::downcast_ref::<INT>(&value)
|
return val.downcast_ref::<INT>().expect(CHECKED).clone().into();
|
||||||
.expect(CHECKED)
|
|
||||||
.clone()
|
|
||||||
.into();
|
|
||||||
}
|
}
|
||||||
#[cfg(not(feature = "no_float"))]
|
#[cfg(not(feature = "no_float"))]
|
||||||
if TypeId::of::<T>() == TypeId::of::<FLOAT>() {
|
if TypeId::of::<T>() == TypeId::of::<FLOAT>() {
|
||||||
return <dyn Any>::downcast_ref::<FLOAT>(&value)
|
return val.downcast_ref::<FLOAT>().expect(CHECKED).clone().into();
|
||||||
.expect(CHECKED)
|
|
||||||
.clone()
|
|
||||||
.into();
|
|
||||||
}
|
}
|
||||||
#[cfg(feature = "decimal")]
|
#[cfg(feature = "decimal")]
|
||||||
if TypeId::of::<T>() == TypeId::of::<Decimal>() {
|
if TypeId::of::<T>() == TypeId::of::<Decimal>() {
|
||||||
return <dyn Any>::downcast_ref::<Decimal>(&value)
|
return val.downcast_ref::<Decimal>().expect(CHECKED).clone().into();
|
||||||
.expect(CHECKED)
|
|
||||||
.clone()
|
|
||||||
.into();
|
|
||||||
}
|
}
|
||||||
if TypeId::of::<T>() == TypeId::of::<bool>() {
|
if TypeId::of::<T>() == TypeId::of::<bool>() {
|
||||||
return <dyn Any>::downcast_ref::<bool>(&value)
|
return val.downcast_ref::<bool>().expect(CHECKED).clone().into();
|
||||||
.expect(CHECKED)
|
|
||||||
.clone()
|
|
||||||
.into();
|
|
||||||
}
|
}
|
||||||
if TypeId::of::<T>() == TypeId::of::<char>() {
|
if TypeId::of::<T>() == TypeId::of::<char>() {
|
||||||
return <dyn Any>::downcast_ref::<char>(&value)
|
return val.downcast_ref::<char>().expect(CHECKED).clone().into();
|
||||||
.expect(CHECKED)
|
|
||||||
.clone()
|
|
||||||
.into();
|
|
||||||
}
|
}
|
||||||
if TypeId::of::<T>() == TypeId::of::<ImmutableString>() {
|
if TypeId::of::<T>() == TypeId::of::<ImmutableString>() {
|
||||||
return <dyn Any>::downcast_ref::<ImmutableString>(&value)
|
return val
|
||||||
|
.downcast_ref::<ImmutableString>()
|
||||||
.expect(CHECKED)
|
.expect(CHECKED)
|
||||||
.clone()
|
.clone()
|
||||||
.into();
|
.into();
|
||||||
}
|
}
|
||||||
if TypeId::of::<T>() == TypeId::of::<&str>() {
|
if TypeId::of::<T>() == TypeId::of::<&str>() {
|
||||||
return <dyn Any>::downcast_ref::<&str>(&value)
|
return val.downcast_ref::<&str>().expect(CHECKED).deref().into();
|
||||||
.expect(CHECKED)
|
|
||||||
.deref()
|
|
||||||
.into();
|
|
||||||
}
|
}
|
||||||
if TypeId::of::<T>() == TypeId::of::<()>() {
|
if TypeId::of::<T>() == TypeId::of::<()>() {
|
||||||
return ().into();
|
return ().into();
|
||||||
@ -1612,77 +1497,77 @@ impl Dynamic {
|
|||||||
|
|
||||||
if TypeId::of::<T>() == TypeId::of::<INT>() {
|
if TypeId::of::<T>() == TypeId::of::<INT>() {
|
||||||
return match &self.0 {
|
return match &self.0 {
|
||||||
Union::Int(value, _, _) => <dyn Any>::downcast_ref::<T>(value),
|
Union::Int(value, _, _) => value.as_any().downcast_ref::<T>(),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
#[cfg(not(feature = "no_float"))]
|
#[cfg(not(feature = "no_float"))]
|
||||||
if TypeId::of::<T>() == TypeId::of::<FLOAT>() {
|
if TypeId::of::<T>() == TypeId::of::<FLOAT>() {
|
||||||
return match &self.0 {
|
return match &self.0 {
|
||||||
Union::Float(value, _, _) => <dyn Any>::downcast_ref::<T>(value.as_ref()),
|
Union::Float(value, _, _) => value.as_ref().as_any().downcast_ref::<T>(),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
#[cfg(feature = "decimal")]
|
#[cfg(feature = "decimal")]
|
||||||
if TypeId::of::<T>() == TypeId::of::<Decimal>() {
|
if TypeId::of::<T>() == TypeId::of::<Decimal>() {
|
||||||
return match &self.0 {
|
return match &self.0 {
|
||||||
Union::Decimal(value, _, _) => <dyn Any>::downcast_ref::<T>(value.as_ref()),
|
Union::Decimal(value, _, _) => value.as_ref().as_any().downcast_ref::<T>(),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
if TypeId::of::<T>() == TypeId::of::<bool>() {
|
if TypeId::of::<T>() == TypeId::of::<bool>() {
|
||||||
return match &self.0 {
|
return match &self.0 {
|
||||||
Union::Bool(value, _, _) => <dyn Any>::downcast_ref::<T>(value),
|
Union::Bool(value, _, _) => value.as_any().downcast_ref::<T>(),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
if TypeId::of::<T>() == TypeId::of::<ImmutableString>() {
|
if TypeId::of::<T>() == TypeId::of::<ImmutableString>() {
|
||||||
return match &self.0 {
|
return match &self.0 {
|
||||||
Union::Str(value, _, _) => <dyn Any>::downcast_ref::<T>(value),
|
Union::Str(value, _, _) => value.as_any().downcast_ref::<T>(),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
if TypeId::of::<T>() == TypeId::of::<char>() {
|
if TypeId::of::<T>() == TypeId::of::<char>() {
|
||||||
return match &self.0 {
|
return match &self.0 {
|
||||||
Union::Char(value, _, _) => <dyn Any>::downcast_ref::<T>(value),
|
Union::Char(value, _, _) => value.as_any().downcast_ref::<T>(),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
#[cfg(not(feature = "no_index"))]
|
#[cfg(not(feature = "no_index"))]
|
||||||
if TypeId::of::<T>() == TypeId::of::<Array>() {
|
if TypeId::of::<T>() == TypeId::of::<Array>() {
|
||||||
return match &self.0 {
|
return match &self.0 {
|
||||||
Union::Array(value, _, _) => <dyn Any>::downcast_ref::<T>(value.as_ref()),
|
Union::Array(value, _, _) => value.as_ref().as_any().downcast_ref::<T>(),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
#[cfg(not(feature = "no_object"))]
|
#[cfg(not(feature = "no_object"))]
|
||||||
if TypeId::of::<T>() == TypeId::of::<Map>() {
|
if TypeId::of::<T>() == TypeId::of::<Map>() {
|
||||||
return match &self.0 {
|
return match &self.0 {
|
||||||
Union::Map(value, _, _) => <dyn Any>::downcast_ref::<T>(value.as_ref()),
|
Union::Map(value, _, _) => value.as_ref().as_any().downcast_ref::<T>(),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
if TypeId::of::<T>() == TypeId::of::<FnPtr>() {
|
if TypeId::of::<T>() == TypeId::of::<FnPtr>() {
|
||||||
return match &self.0 {
|
return match &self.0 {
|
||||||
Union::FnPtr(value, _, _) => <dyn Any>::downcast_ref::<T>(value.as_ref()),
|
Union::FnPtr(value, _, _) => value.as_ref().as_any().downcast_ref::<T>(),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
#[cfg(not(feature = "no_std"))]
|
#[cfg(not(feature = "no_std"))]
|
||||||
if TypeId::of::<T>() == TypeId::of::<Instant>() {
|
if TypeId::of::<T>() == TypeId::of::<Instant>() {
|
||||||
return match &self.0 {
|
return match &self.0 {
|
||||||
Union::TimeStamp(value, _, _) => <dyn Any>::downcast_ref::<T>(value.as_ref()),
|
Union::TimeStamp(value, _, _) => value.as_ref().as_any().downcast_ref::<T>(),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
if TypeId::of::<T>() == TypeId::of::<()>() {
|
if TypeId::of::<T>() == TypeId::of::<()>() {
|
||||||
return match &self.0 {
|
return match &self.0 {
|
||||||
Union::Unit(value, _, _) => <dyn Any>::downcast_ref::<T>(value),
|
Union::Unit(value, _, _) => value.as_any().downcast_ref::<T>(),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
if TypeId::of::<T>() == TypeId::of::<Dynamic>() {
|
if TypeId::of::<T>() == TypeId::of::<Dynamic>() {
|
||||||
return <dyn Any>::downcast_ref::<T>(self);
|
return self.as_any().downcast_ref::<T>();
|
||||||
}
|
}
|
||||||
|
|
||||||
match &self.0 {
|
match &self.0 {
|
||||||
@ -1702,77 +1587,77 @@ impl Dynamic {
|
|||||||
|
|
||||||
if TypeId::of::<T>() == TypeId::of::<INT>() {
|
if TypeId::of::<T>() == TypeId::of::<INT>() {
|
||||||
return match &mut self.0 {
|
return match &mut self.0 {
|
||||||
Union::Int(value, _, _) => <dyn Any>::downcast_mut::<T>(value),
|
Union::Int(value, _, _) => value.as_mut_any().downcast_mut::<T>(),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
#[cfg(not(feature = "no_float"))]
|
#[cfg(not(feature = "no_float"))]
|
||||||
if TypeId::of::<T>() == TypeId::of::<FLOAT>() {
|
if TypeId::of::<T>() == TypeId::of::<FLOAT>() {
|
||||||
return match &mut self.0 {
|
return match &mut self.0 {
|
||||||
Union::Float(value, _, _) => <dyn Any>::downcast_mut::<T>(value.as_mut()),
|
Union::Float(value, _, _) => value.as_mut().as_mut_any().downcast_mut::<T>(),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
#[cfg(feature = "decimal")]
|
#[cfg(feature = "decimal")]
|
||||||
if TypeId::of::<T>() == TypeId::of::<Decimal>() {
|
if TypeId::of::<T>() == TypeId::of::<Decimal>() {
|
||||||
return match &mut self.0 {
|
return match &mut self.0 {
|
||||||
Union::Decimal(value, _, _) => <dyn Any>::downcast_mut::<T>(value.as_mut()),
|
Union::Decimal(value, _, _) => value.as_mut().as_mut_any().downcast_mut::<T>(),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
if TypeId::of::<T>() == TypeId::of::<bool>() {
|
if TypeId::of::<T>() == TypeId::of::<bool>() {
|
||||||
return match &mut self.0 {
|
return match &mut self.0 {
|
||||||
Union::Bool(value, _, _) => <dyn Any>::downcast_mut::<T>(value),
|
Union::Bool(value, _, _) => value.as_mut_any().downcast_mut::<T>(),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
if TypeId::of::<T>() == TypeId::of::<ImmutableString>() {
|
if TypeId::of::<T>() == TypeId::of::<ImmutableString>() {
|
||||||
return match &mut self.0 {
|
return match &mut self.0 {
|
||||||
Union::Str(value, _, _) => <dyn Any>::downcast_mut::<T>(value),
|
Union::Str(value, _, _) => value.as_mut_any().downcast_mut::<T>(),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
if TypeId::of::<T>() == TypeId::of::<char>() {
|
if TypeId::of::<T>() == TypeId::of::<char>() {
|
||||||
return match &mut self.0 {
|
return match &mut self.0 {
|
||||||
Union::Char(value, _, _) => <dyn Any>::downcast_mut::<T>(value),
|
Union::Char(value, _, _) => value.as_mut_any().downcast_mut::<T>(),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
#[cfg(not(feature = "no_index"))]
|
#[cfg(not(feature = "no_index"))]
|
||||||
if TypeId::of::<T>() == TypeId::of::<Array>() {
|
if TypeId::of::<T>() == TypeId::of::<Array>() {
|
||||||
return match &mut self.0 {
|
return match &mut self.0 {
|
||||||
Union::Array(value, _, _) => <dyn Any>::downcast_mut::<T>(value.as_mut()),
|
Union::Array(value, _, _) => value.as_mut().as_mut_any().downcast_mut::<T>(),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
#[cfg(not(feature = "no_object"))]
|
#[cfg(not(feature = "no_object"))]
|
||||||
if TypeId::of::<T>() == TypeId::of::<Map>() {
|
if TypeId::of::<T>() == TypeId::of::<Map>() {
|
||||||
return match &mut self.0 {
|
return match &mut self.0 {
|
||||||
Union::Map(value, _, _) => <dyn Any>::downcast_mut::<T>(value.as_mut()),
|
Union::Map(value, _, _) => value.as_mut().as_mut_any().downcast_mut::<T>(),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
if TypeId::of::<T>() == TypeId::of::<FnPtr>() {
|
if TypeId::of::<T>() == TypeId::of::<FnPtr>() {
|
||||||
return match &mut self.0 {
|
return match &mut self.0 {
|
||||||
Union::FnPtr(value, _, _) => <dyn Any>::downcast_mut::<T>(value.as_mut()),
|
Union::FnPtr(value, _, _) => value.as_mut().as_mut_any().downcast_mut::<T>(),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
#[cfg(not(feature = "no_std"))]
|
#[cfg(not(feature = "no_std"))]
|
||||||
if TypeId::of::<T>() == TypeId::of::<Instant>() {
|
if TypeId::of::<T>() == TypeId::of::<Instant>() {
|
||||||
return match &mut self.0 {
|
return match &mut self.0 {
|
||||||
Union::TimeStamp(value, _, _) => <dyn Any>::downcast_mut::<T>(value.as_mut()),
|
Union::TimeStamp(value, _, _) => value.as_mut().as_mut_any().downcast_mut::<T>(),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
if TypeId::of::<T>() == TypeId::of::<()>() {
|
if TypeId::of::<T>() == TypeId::of::<()>() {
|
||||||
return match &mut self.0 {
|
return match &mut self.0 {
|
||||||
Union::Unit(value, _, _) => <dyn Any>::downcast_mut::<T>(value),
|
Union::Unit(value, _, _) => value.as_mut_any().downcast_mut::<T>(),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
if TypeId::of::<T>() == TypeId::of::<Dynamic>() {
|
if TypeId::of::<T>() == TypeId::of::<Dynamic>() {
|
||||||
return <dyn Any>::downcast_mut::<T>(self);
|
return self.as_mut_any().downcast_mut::<T>();
|
||||||
}
|
}
|
||||||
|
|
||||||
match &mut self.0 {
|
match &mut self.0 {
|
||||||
@ -1825,8 +1710,8 @@ impl Dynamic {
|
|||||||
#[cfg(feature = "decimal")]
|
#[cfg(feature = "decimal")]
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn as_decimal(&self) -> Result<Decimal, &'static str> {
|
pub fn as_decimal(&self) -> Result<Decimal, &'static str> {
|
||||||
match &self.0 {
|
match self.0 {
|
||||||
Union::Decimal(n, _, _) => Ok(**n),
|
Union::Decimal(ref n, _, _) => Ok(**n),
|
||||||
#[cfg(not(feature = "no_closure"))]
|
#[cfg(not(feature = "no_closure"))]
|
||||||
Union::Shared(_, _, _) => self.read_lock().map(|v| *v).ok_or_else(|| self.type_name()),
|
Union::Shared(_, _, _) => self.read_lock().map(|v| *v).ok_or_else(|| self.type_name()),
|
||||||
_ => Err(self.type_name()),
|
_ => Err(self.type_name()),
|
||||||
@ -1862,8 +1747,8 @@ impl Dynamic {
|
|||||||
/// Panics if the value is shared.
|
/// Panics if the value is shared.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub(crate) fn as_str_ref(&self) -> Result<&str, &'static str> {
|
pub(crate) fn as_str_ref(&self) -> Result<&str, &'static str> {
|
||||||
match &self.0 {
|
match self.0 {
|
||||||
Union::Str(s, _, _) => Ok(s),
|
Union::Str(ref s, _, _) => Ok(s),
|
||||||
#[cfg(not(feature = "no_closure"))]
|
#[cfg(not(feature = "no_closure"))]
|
||||||
Union::Shared(_, _, _) => panic!("as_str() cannot be called on shared values"),
|
Union::Shared(_, _, _) => panic!("as_str() cannot be called on shared values"),
|
||||||
_ => Err(self.type_name()),
|
_ => Err(self.type_name()),
|
||||||
|
@ -2603,9 +2603,10 @@ impl Engine {
|
|||||||
|
|
||||||
err_map.insert("message".into(), err.to_string().into());
|
err_map.insert("message".into(), err.to_string().into());
|
||||||
|
|
||||||
if let Some(ref source) = state.source {
|
state
|
||||||
err_map.insert("source".into(), source.into());
|
.source
|
||||||
}
|
.as_ref()
|
||||||
|
.map(|source| err_map.insert("source".into(), source.into()));
|
||||||
|
|
||||||
if err_pos.is_none() {
|
if err_pos.is_none() {
|
||||||
// No position info
|
// No position info
|
||||||
@ -2628,9 +2629,9 @@ impl Engine {
|
|||||||
let orig_scope_len = scope.len();
|
let orig_scope_len = scope.len();
|
||||||
state.scope_level += 1;
|
state.scope_level += 1;
|
||||||
|
|
||||||
if let Some(Ident { name, .. }) = err_var {
|
err_var.as_ref().map(|Ident { name, .. }| {
|
||||||
scope.push(unsafe_cast_var_name_to_lifetime(&name), err_value);
|
scope.push(unsafe_cast_var_name_to_lifetime(name), err_value)
|
||||||
}
|
});
|
||||||
|
|
||||||
let result = self.eval_stmt_block(
|
let result = self.eval_stmt_block(
|
||||||
scope, mods, state, lib, this_ptr, catch_stmt, true, level,
|
scope, mods, state, lib, this_ptr, catch_stmt, true, level,
|
||||||
@ -2716,9 +2717,9 @@ impl Engine {
|
|||||||
};
|
};
|
||||||
|
|
||||||
if let Some(global) = global {
|
if let Some(global) = global {
|
||||||
let global = Shared::get_mut(global)
|
Shared::get_mut(global)
|
||||||
.expect("never fails because the global module is never shared");
|
.expect("never fails because the global module is never shared")
|
||||||
global.set_var(name.clone(), value.clone());
|
.set_var(name.clone(), value.clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2735,9 +2736,8 @@ impl Engine {
|
|||||||
scope.push_dynamic_value(var_name, entry_type, value);
|
scope.push_dynamic_value(var_name, entry_type, value);
|
||||||
|
|
||||||
#[cfg(not(feature = "no_module"))]
|
#[cfg(not(feature = "no_module"))]
|
||||||
if let Some(alias) = _alias {
|
_alias.map(|alias| scope.add_entry_alias(scope.len() - 1, alias));
|
||||||
scope.add_entry_alias(scope.len() - 1, alias);
|
|
||||||
}
|
|
||||||
Ok(Dynamic::UNIT)
|
Ok(Dynamic::UNIT)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2773,7 +2773,7 @@ impl Engine {
|
|||||||
self.module_resolver.resolve(self, source, &path, expr_pos)
|
self.module_resolver.resolve(self, source, &path, expr_pos)
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
if let Some(name) = export.as_ref().map(|x| x.name.clone()) {
|
export.as_ref().map(|x| x.name.clone()).map(|name| {
|
||||||
if !module.is_indexed() {
|
if !module.is_indexed() {
|
||||||
// Index the module (making a clone copy if necessary) if it is not indexed
|
// Index the module (making a clone copy if necessary) if it is not indexed
|
||||||
let mut module = crate::fn_native::shared_take_or_clone(module);
|
let mut module = crate::fn_native::shared_take_or_clone(module);
|
||||||
@ -2782,7 +2782,7 @@ impl Engine {
|
|||||||
} else {
|
} else {
|
||||||
mods.push(name, module);
|
mods.push(name, module);
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
|
|
||||||
state.modules += 1;
|
state.modules += 1;
|
||||||
|
|
||||||
@ -2810,14 +2810,14 @@ impl Engine {
|
|||||||
// Share statement
|
// Share statement
|
||||||
#[cfg(not(feature = "no_closure"))]
|
#[cfg(not(feature = "no_closure"))]
|
||||||
Stmt::Share(name) => {
|
Stmt::Share(name) => {
|
||||||
if let Some((index, _)) = scope.get_index(name) {
|
scope.get_index(name).map(|(index, _)| {
|
||||||
let val = scope.get_mut_by_index(index);
|
let val = scope.get_mut_by_index(index);
|
||||||
|
|
||||||
if !val.is_shared() {
|
if !val.is_shared() {
|
||||||
// Replace the variable with a shared value.
|
// Replace the variable with a shared value.
|
||||||
*val = std::mem::take(val).into_shared();
|
*val = std::mem::take(val).into_shared();
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
Ok(Dynamic::UNIT)
|
Ok(Dynamic::UNIT)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -2961,7 +2961,7 @@ impl Engine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Report progress - only in steps
|
// Report progress - only in steps
|
||||||
if let Some(progress) = &self.progress {
|
if let Some(ref progress) = self.progress {
|
||||||
if let Some(token) = progress(state.operations) {
|
if let Some(token) = progress(state.operations) {
|
||||||
// Terminate script if progress returns a termination token
|
// Terminate script if progress returns a termination token
|
||||||
return EvalAltResult::ErrorTerminated(token, pos).into();
|
return EvalAltResult::ErrorTerminated(token, pos).into();
|
||||||
|
@ -13,6 +13,8 @@ use crate::FLOAT;
|
|||||||
#[cfg(feature = "decimal")]
|
#[cfg(feature = "decimal")]
|
||||||
use rust_decimal::Decimal;
|
use rust_decimal::Decimal;
|
||||||
|
|
||||||
|
const BUILTIN: &str = "never fails because this is built-in code and the type is already checked";
|
||||||
|
|
||||||
/// Is the type a numeric type?
|
/// Is the type a numeric type?
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn is_numeric(type_id: TypeId) -> bool {
|
fn is_numeric(type_id: TypeId) -> bool {
|
||||||
@ -75,22 +77,22 @@ pub fn get_builtin_binary_op_fn(
|
|||||||
macro_rules! impl_op {
|
macro_rules! impl_op {
|
||||||
($xx:ident $op:tt $yy:ident) => {
|
($xx:ident $op:tt $yy:ident) => {
|
||||||
return Some(|_, args| {
|
return Some(|_, args| {
|
||||||
let x = &*args[0].read_lock::<$xx>().unwrap();
|
let x = &*args[0].read_lock::<$xx>().expect(BUILTIN);
|
||||||
let y = &*args[1].read_lock::<$yy>().unwrap();
|
let y = &*args[1].read_lock::<$yy>().expect(BUILTIN);
|
||||||
Ok((x $op y).into())
|
Ok((x $op y).into())
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
($xx:ident . $func:ident ( $yy:ty )) => {
|
($xx:ident . $func:ident ( $yy:ty )) => {
|
||||||
return Some(|_, args| {
|
return Some(|_, args| {
|
||||||
let x = &*args[0].read_lock::<$xx>().unwrap();
|
let x = &*args[0].read_lock::<$xx>().expect(BUILTIN);
|
||||||
let y = &*args[1].read_lock::<$yy>().unwrap();
|
let y = &*args[1].read_lock::<$yy>().expect(BUILTIN);
|
||||||
Ok(x.$func(y).into())
|
Ok(x.$func(y).into())
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
($xx:ident . $func:ident ( $yy:ident . $yyy:ident () )) => {
|
($xx:ident . $func:ident ( $yy:ident . $yyy:ident () )) => {
|
||||||
return Some(|_, args| {
|
return Some(|_, args| {
|
||||||
let x = &*args[0].read_lock::<$xx>().unwrap();
|
let x = &*args[0].read_lock::<$xx>().expect(BUILTIN);
|
||||||
let y = &*args[1].read_lock::<$yy>().unwrap();
|
let y = &*args[1].read_lock::<$yy>().expect(BUILTIN);
|
||||||
Ok(x.$func(y.$yyy()).into())
|
Ok(x.$func(y.$yyy()).into())
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
@ -102,43 +104,43 @@ pub fn get_builtin_binary_op_fn(
|
|||||||
};
|
};
|
||||||
($base:ty => $xx:ident $op:tt $yy:ident) => {
|
($base:ty => $xx:ident $op:tt $yy:ident) => {
|
||||||
return Some(|_, args| {
|
return Some(|_, args| {
|
||||||
let x = args[0].$xx().unwrap() as $base;
|
let x = args[0].$xx().expect(BUILTIN) as $base;
|
||||||
let y = args[1].$yy().unwrap() as $base;
|
let y = args[1].$yy().expect(BUILTIN) as $base;
|
||||||
Ok((x $op y).into())
|
Ok((x $op y).into())
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
($base:ty => $xx:ident . $func:ident ( $yy:ident as $yyy:ty)) => {
|
($base:ty => $xx:ident . $func:ident ( $yy:ident as $yyy:ty)) => {
|
||||||
return Some(|_, args| {
|
return Some(|_, args| {
|
||||||
let x = args[0].$xx().unwrap() as $base;
|
let x = args[0].$xx().expect(BUILTIN) as $base;
|
||||||
let y = args[1].$yy().unwrap() as $base;
|
let y = args[1].$yy().expect(BUILTIN) as $base;
|
||||||
Ok(x.$func(y as $yyy).into())
|
Ok(x.$func(y as $yyy).into())
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
($base:ty => $func:ident ( $xx:ident, $yy:ident )) => {
|
($base:ty => $func:ident ( $xx:ident, $yy:ident )) => {
|
||||||
return Some(|_, args| {
|
return Some(|_, args| {
|
||||||
let x = args[0].$xx().unwrap() as $base;
|
let x = args[0].$xx().expect(BUILTIN) as $base;
|
||||||
let y = args[1].$yy().unwrap() as $base;
|
let y = args[1].$yy().expect(BUILTIN) as $base;
|
||||||
$func(x, y).map(Into::<Dynamic>::into)
|
$func(x, y).map(Into::<Dynamic>::into)
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
(from $base:ty => $xx:ident $op:tt $yy:ident) => {
|
(from $base:ty => $xx:ident $op:tt $yy:ident) => {
|
||||||
return Some(|_, args| {
|
return Some(|_, args| {
|
||||||
let x = <$base>::from(args[0].$xx().unwrap());
|
let x = <$base>::from(args[0].$xx().expect(BUILTIN));
|
||||||
let y = <$base>::from(args[1].$yy().unwrap());
|
let y = <$base>::from(args[1].$yy().expect(BUILTIN));
|
||||||
Ok((x $op y).into())
|
Ok((x $op y).into())
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
(from $base:ty => $xx:ident . $func:ident ( $yy:ident )) => {
|
(from $base:ty => $xx:ident . $func:ident ( $yy:ident )) => {
|
||||||
return Some(|_, args| {
|
return Some(|_, args| {
|
||||||
let x = <$base>::from(args[0].$xx().unwrap());
|
let x = <$base>::from(args[0].$xx().expect(BUILTIN));
|
||||||
let y = <$base>::from(args[1].$yy().unwrap());
|
let y = <$base>::from(args[1].$yy().expect(BUILTIN));
|
||||||
Ok(x.$func(y).into())
|
Ok(x.$func(y).into())
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
(from $base:ty => $func:ident ( $xx:ident, $yy:ident )) => {
|
(from $base:ty => $func:ident ( $xx:ident, $yy:ident )) => {
|
||||||
return Some(|_, args| {
|
return Some(|_, args| {
|
||||||
let x = <$base>::from(args[0].$xx().unwrap());
|
let x = <$base>::from(args[0].$xx().expect(BUILTIN));
|
||||||
let y = <$base>::from(args[1].$yy().unwrap());
|
let y = <$base>::from(args[1].$yy().expect(BUILTIN));
|
||||||
$func(x, y).map(Into::<Dynamic>::into)
|
$func(x, y).map(Into::<Dynamic>::into)
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
@ -175,7 +177,7 @@ pub fn get_builtin_binary_op_fn(
|
|||||||
($x:ty, $xx:ident, $y:ty, $yy:ident) => {
|
($x:ty, $xx:ident, $y:ty, $yy:ident) => {
|
||||||
#[cfg(feature = "decimal")]
|
#[cfg(feature = "decimal")]
|
||||||
if types_pair == (TypeId::of::<$x>(), TypeId::of::<$y>()) {
|
if types_pair == (TypeId::of::<$x>(), TypeId::of::<$y>()) {
|
||||||
if cfg!(not(feature = "unchecked")) {
|
if cfg!(not(feature = "unBUILTIN")) {
|
||||||
use crate::packages::arithmetic::decimal_functions::*;
|
use crate::packages::arithmetic::decimal_functions::*;
|
||||||
|
|
||||||
match op {
|
match op {
|
||||||
@ -222,8 +224,8 @@ pub fn get_builtin_binary_op_fn(
|
|||||||
if types_pair == (TypeId::of::<char>(), TypeId::of::<ImmutableString>()) {
|
if types_pair == (TypeId::of::<char>(), TypeId::of::<ImmutableString>()) {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn get_s1s2(args: &FnCallArgs) -> ([char; 2], [char; 2]) {
|
fn get_s1s2(args: &FnCallArgs) -> ([char; 2], [char; 2]) {
|
||||||
let x = args[0].as_char().unwrap();
|
let x = args[0].as_char().expect(BUILTIN);
|
||||||
let y = &*args[1].read_lock::<ImmutableString>().unwrap();
|
let y = &*args[1].read_lock::<ImmutableString>().expect(BUILTIN);
|
||||||
let s1 = [x, '\0'];
|
let s1 = [x, '\0'];
|
||||||
let mut y = y.chars();
|
let mut y = y.chars();
|
||||||
let s2 = [y.next().unwrap_or('\0'), y.next().unwrap_or('\0')];
|
let s2 = [y.next().unwrap_or('\0'), y.next().unwrap_or('\0')];
|
||||||
@ -233,8 +235,8 @@ pub fn get_builtin_binary_op_fn(
|
|||||||
match op {
|
match op {
|
||||||
"+" => {
|
"+" => {
|
||||||
return Some(|_, args| {
|
return Some(|_, args| {
|
||||||
let x = args[0].as_char().unwrap();
|
let x = args[0].as_char().expect(BUILTIN);
|
||||||
let y = &*args[1].read_lock::<ImmutableString>().unwrap();
|
let y = &*args[1].read_lock::<ImmutableString>().expect(BUILTIN);
|
||||||
Ok(format!("{}{}", x, y).into())
|
Ok(format!("{}{}", x, y).into())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -251,8 +253,8 @@ pub fn get_builtin_binary_op_fn(
|
|||||||
if types_pair == (TypeId::of::<ImmutableString>(), TypeId::of::<char>()) {
|
if types_pair == (TypeId::of::<ImmutableString>(), TypeId::of::<char>()) {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn get_s1s2(args: &FnCallArgs) -> ([char; 2], [char; 2]) {
|
fn get_s1s2(args: &FnCallArgs) -> ([char; 2], [char; 2]) {
|
||||||
let x = &*args[0].read_lock::<ImmutableString>().unwrap();
|
let x = &*args[0].read_lock::<ImmutableString>().expect(BUILTIN);
|
||||||
let y = args[1].as_char().unwrap();
|
let y = args[1].as_char().expect(BUILTIN);
|
||||||
let mut x = x.chars();
|
let mut x = x.chars();
|
||||||
let s1 = [x.next().unwrap_or('\0'), x.next().unwrap_or('\0')];
|
let s1 = [x.next().unwrap_or('\0'), x.next().unwrap_or('\0')];
|
||||||
let s2 = [y, '\0'];
|
let s2 = [y, '\0'];
|
||||||
@ -262,15 +264,15 @@ pub fn get_builtin_binary_op_fn(
|
|||||||
match op {
|
match op {
|
||||||
"+" => {
|
"+" => {
|
||||||
return Some(|_, args| {
|
return Some(|_, args| {
|
||||||
let x = &*args[0].read_lock::<ImmutableString>().unwrap();
|
let x = &*args[0].read_lock::<ImmutableString>().expect(BUILTIN);
|
||||||
let y = args[1].as_char().unwrap();
|
let y = args[1].as_char().expect(BUILTIN);
|
||||||
Ok((x + y).into())
|
Ok((x + y).into())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
"-" => {
|
"-" => {
|
||||||
return Some(|_, args| {
|
return Some(|_, args| {
|
||||||
let x = &*args[0].read_lock::<ImmutableString>().unwrap();
|
let x = &*args[0].read_lock::<ImmutableString>().expect(BUILTIN);
|
||||||
let y = args[1].as_char().unwrap();
|
let y = args[1].as_char().expect(BUILTIN);
|
||||||
Ok((x - y).into())
|
Ok((x - y).into())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -282,8 +284,8 @@ pub fn get_builtin_binary_op_fn(
|
|||||||
"<=" => impl_op!(get_s1s2(<=)),
|
"<=" => impl_op!(get_s1s2(<=)),
|
||||||
OP_CONTAINS => {
|
OP_CONTAINS => {
|
||||||
return Some(|_, args| {
|
return Some(|_, args| {
|
||||||
let s = &*args[0].read_lock::<ImmutableString>().unwrap();
|
let s = &*args[0].read_lock::<ImmutableString>().expect(BUILTIN);
|
||||||
let c = args[1].as_char().unwrap();
|
let c = args[1].as_char().expect(BUILTIN);
|
||||||
Ok((s.contains(c)).into())
|
Ok((s.contains(c)).into())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -314,7 +316,7 @@ pub fn get_builtin_binary_op_fn(
|
|||||||
// Beyond here, type1 == type2
|
// Beyond here, type1 == type2
|
||||||
|
|
||||||
if type1 == TypeId::of::<INT>() {
|
if type1 == TypeId::of::<INT>() {
|
||||||
if cfg!(not(feature = "unchecked")) {
|
if cfg!(not(feature = "unBUILTIN")) {
|
||||||
use crate::packages::arithmetic::arith_basic::INT::functions::*;
|
use crate::packages::arithmetic::arith_basic::INT::functions::*;
|
||||||
|
|
||||||
match op {
|
match op {
|
||||||
@ -383,8 +385,8 @@ pub fn get_builtin_binary_op_fn(
|
|||||||
"<=" => impl_op!(ImmutableString <= ImmutableString),
|
"<=" => impl_op!(ImmutableString <= ImmutableString),
|
||||||
OP_CONTAINS => {
|
OP_CONTAINS => {
|
||||||
return Some(|_, args| {
|
return Some(|_, args| {
|
||||||
let s1 = &*args[0].read_lock::<ImmutableString>().unwrap();
|
let s1 = &*args[0].read_lock::<ImmutableString>().expect(BUILTIN);
|
||||||
let s2 = &*args[1].read_lock::<ImmutableString>().unwrap();
|
let s2 = &*args[1].read_lock::<ImmutableString>().expect(BUILTIN);
|
||||||
Ok((s1.contains(s2.as_str())).into())
|
Ok((s1.contains(s2.as_str())).into())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -396,8 +398,8 @@ pub fn get_builtin_binary_op_fn(
|
|||||||
match op {
|
match op {
|
||||||
"+" => {
|
"+" => {
|
||||||
return Some(|_, args| {
|
return Some(|_, args| {
|
||||||
let x = args[0].as_char().unwrap();
|
let x = args[0].as_char().expect(BUILTIN);
|
||||||
let y = args[1].as_char().unwrap();
|
let y = args[1].as_char().expect(BUILTIN);
|
||||||
Ok(format!("{}{}", x, y).into())
|
Ok(format!("{}{}", x, y).into())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -440,55 +442,55 @@ pub fn get_builtin_op_assignment_fn(
|
|||||||
macro_rules! impl_op {
|
macro_rules! impl_op {
|
||||||
($x:ty = x $op:tt $yy:ident) => {
|
($x:ty = x $op:tt $yy:ident) => {
|
||||||
return Some(|_, args| {
|
return Some(|_, args| {
|
||||||
let x = args[0].$yy().unwrap();
|
let x = args[0].$yy().expect(BUILTIN);
|
||||||
let y = args[1].$yy().unwrap() as $x;
|
let y = args[1].$yy().expect(BUILTIN) as $x;
|
||||||
Ok((*args[0].write_lock::<$x>().unwrap() = x $op y).into())
|
Ok((*args[0].write_lock::<$x>().expect(BUILTIN) = x $op y).into())
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
($x:ident $op:tt $yy:ident) => {
|
($x:ident $op:tt $yy:ident) => {
|
||||||
return Some(|_, args| {
|
return Some(|_, args| {
|
||||||
let y = args[1].$yy().unwrap() as $x;
|
let y = args[1].$yy().expect(BUILTIN) as $x;
|
||||||
Ok((*args[0].write_lock::<$x>().unwrap() $op y).into())
|
Ok((*args[0].write_lock::<$x>().expect(BUILTIN) $op y).into())
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
($x:ident $op:tt $yy:ident as $yyy:ty) => {
|
($x:ident $op:tt $yy:ident as $yyy:ty) => {
|
||||||
return Some(|_, args| {
|
return Some(|_, args| {
|
||||||
let y = args[1].$yy().unwrap() as $yyy;
|
let y = args[1].$yy().expect(BUILTIN) as $yyy;
|
||||||
Ok((*args[0].write_lock::<$x>().unwrap() $op y).into())
|
Ok((*args[0].write_lock::<$x>().expect(BUILTIN) $op y).into())
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
($x:ty => $xx:ident . $func:ident ( $yy:ident as $yyy:ty )) => {
|
($x:ty => $xx:ident . $func:ident ( $yy:ident as $yyy:ty )) => {
|
||||||
return Some(|_, args| {
|
return Some(|_, args| {
|
||||||
let x = args[0].$xx().unwrap();
|
let x = args[0].$xx().expect(BUILTIN);
|
||||||
let y = args[1].$yy().unwrap() as $x;
|
let y = args[1].$yy().expect(BUILTIN) as $x;
|
||||||
Ok((*args[0].write_lock::<$x>().unwrap() = x.$func(y as $yyy)).into())
|
Ok((*args[0].write_lock::<$x>().expect(BUILTIN) = x.$func(y as $yyy)).into())
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
($x:ty => $func:ident ( $xx:ident, $yy:ident )) => {
|
($x:ty => $func:ident ( $xx:ident, $yy:ident )) => {
|
||||||
return Some(|_, args| {
|
return Some(|_, args| {
|
||||||
let x = args[0].$xx().unwrap();
|
let x = args[0].$xx().expect(BUILTIN);
|
||||||
let y = args[1].$yy().unwrap() as $x;
|
let y = args[1].$yy().expect(BUILTIN) as $x;
|
||||||
Ok((*args[0].write_lock().unwrap() = $func(x, y)?).into())
|
Ok((*args[0].write_lock().expect(BUILTIN) = $func(x, y)?).into())
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
(from $x:ident $op:tt $yy:ident) => {
|
(from $x:ident $op:tt $yy:ident) => {
|
||||||
return Some(|_, args| {
|
return Some(|_, args| {
|
||||||
let y = <$x>::from(args[1].$yy().unwrap());
|
let y = <$x>::from(args[1].$yy().expect(BUILTIN));
|
||||||
Ok((*args[0].write_lock::<$x>().unwrap() $op y).into())
|
Ok((*args[0].write_lock::<$x>().expect(BUILTIN) $op y).into())
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
(from $x:ty => $xx:ident . $func:ident ( $yy:ident )) => {
|
(from $x:ty => $xx:ident . $func:ident ( $yy:ident )) => {
|
||||||
return Some(|_, args| {
|
return Some(|_, args| {
|
||||||
let x = args[0].$xx().unwrap();
|
let x = args[0].$xx().expect(BUILTIN);
|
||||||
let y = <$x>::from(args[1].$yy().unwrap());
|
let y = <$x>::from(args[1].$yy().expect(BUILTIN));
|
||||||
Ok((*args[0].write_lock::<$x>().unwrap() = x.$func(y)).into())
|
Ok((*args[0].write_lock::<$x>().expect(BUILTIN) = x.$func(y)).into())
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
(from $x:ty => $func:ident ( $xx:ident, $yy:ident )) => {
|
(from $x:ty => $func:ident ( $xx:ident, $yy:ident )) => {
|
||||||
return Some(|_, args| {
|
return Some(|_, args| {
|
||||||
let x = args[0].$xx().unwrap();
|
let x = args[0].$xx().expect(BUILTIN);
|
||||||
let y = <$x>::from(args[1].$yy().unwrap());
|
let y = <$x>::from(args[1].$yy().expect(BUILTIN));
|
||||||
Ok((*args[0].write_lock().unwrap() = $func(x, y)?).into())
|
Ok((*args[0].write_lock().expect(BUILTIN) = $func(x, y)?).into())
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -517,7 +519,7 @@ pub fn get_builtin_op_assignment_fn(
|
|||||||
($x:ident, $xx:ident, $y:ty, $yy:ident) => {
|
($x:ident, $xx:ident, $y:ty, $yy:ident) => {
|
||||||
#[cfg(feature = "decimal")]
|
#[cfg(feature = "decimal")]
|
||||||
if types_pair == (TypeId::of::<$x>(), TypeId::of::<$y>()) {
|
if types_pair == (TypeId::of::<$x>(), TypeId::of::<$y>()) {
|
||||||
if cfg!(not(feature = "unchecked")) {
|
if cfg!(not(feature = "unBUILTIN")) {
|
||||||
use crate::packages::arithmetic::decimal_functions::*;
|
use crate::packages::arithmetic::decimal_functions::*;
|
||||||
|
|
||||||
match op {
|
match op {
|
||||||
@ -562,10 +564,15 @@ pub fn get_builtin_op_assignment_fn(
|
|||||||
match op {
|
match op {
|
||||||
"+=" => {
|
"+=" => {
|
||||||
return Some(|_, args| {
|
return Some(|_, args| {
|
||||||
let mut ch = args[0].as_char().unwrap().to_string();
|
let mut ch = args[0].as_char().expect(BUILTIN).to_string();
|
||||||
ch.push_str(args[1].read_lock::<ImmutableString>().unwrap().as_str());
|
ch.push_str(
|
||||||
|
args[1]
|
||||||
|
.read_lock::<ImmutableString>()
|
||||||
|
.expect(BUILTIN)
|
||||||
|
.as_str(),
|
||||||
|
);
|
||||||
|
|
||||||
let mut x = args[0].write_lock::<Dynamic>().unwrap();
|
let mut x = args[0].write_lock::<Dynamic>().expect(BUILTIN);
|
||||||
Ok((*x = ch.into()).into())
|
Ok((*x = ch.into()).into())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -580,7 +587,7 @@ pub fn get_builtin_op_assignment_fn(
|
|||||||
|
|
||||||
// Beyond here, type1 == type2
|
// Beyond here, type1 == type2
|
||||||
if type1 == TypeId::of::<INT>() {
|
if type1 == TypeId::of::<INT>() {
|
||||||
if cfg!(not(feature = "unchecked")) {
|
if cfg!(not(feature = "unBUILTIN")) {
|
||||||
use crate::packages::arithmetic::arith_basic::INT::functions::*;
|
use crate::packages::arithmetic::arith_basic::INT::functions::*;
|
||||||
|
|
||||||
match op {
|
match op {
|
||||||
@ -628,8 +635,8 @@ pub fn get_builtin_op_assignment_fn(
|
|||||||
match op {
|
match op {
|
||||||
"+=" => {
|
"+=" => {
|
||||||
return Some(|_, args| {
|
return Some(|_, args| {
|
||||||
let y = args[1].as_char().unwrap();
|
let y = args[1].as_char().expect(BUILTIN);
|
||||||
let mut x = args[0].write_lock::<Dynamic>().unwrap();
|
let mut x = args[0].write_lock::<Dynamic>().expect(BUILTIN);
|
||||||
Ok((*x = format!("{}{}", *x, y).into()).into())
|
Ok((*x = format!("{}{}", *x, y).into()).into())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -641,17 +648,17 @@ pub fn get_builtin_op_assignment_fn(
|
|||||||
match op {
|
match op {
|
||||||
"+=" => {
|
"+=" => {
|
||||||
return Some(|_, args| {
|
return Some(|_, args| {
|
||||||
let (first, second) = args.split_first_mut().unwrap();
|
let (first, second) = args.split_first_mut().expect(BUILTIN);
|
||||||
let mut x = first.write_lock::<ImmutableString>().unwrap();
|
let mut x = first.write_lock::<ImmutableString>().expect(BUILTIN);
|
||||||
let y = &*second[0].read_lock::<ImmutableString>().unwrap();
|
let y = &*second[0].read_lock::<ImmutableString>().expect(BUILTIN);
|
||||||
Ok((*x += y).into())
|
Ok((*x += y).into())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
"-=" => {
|
"-=" => {
|
||||||
return Some(|_, args| {
|
return Some(|_, args| {
|
||||||
let (first, second) = args.split_first_mut().unwrap();
|
let (first, second) = args.split_first_mut().expect(BUILTIN);
|
||||||
let mut x = first.write_lock::<ImmutableString>().unwrap();
|
let mut x = first.write_lock::<ImmutableString>().expect(BUILTIN);
|
||||||
let y = &*second[0].read_lock::<ImmutableString>().unwrap();
|
let y = &*second[0].read_lock::<ImmutableString>().expect(BUILTIN);
|
||||||
Ok((*x -= y).into())
|
Ok((*x -= y).into())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -70,7 +70,7 @@ impl<'a> ArgBackup<'a> {
|
|||||||
//
|
//
|
||||||
// We can do this here because, before the end of this scope, we'd restore the original reference
|
// We can do this here because, before the end of this scope, we'd restore the original reference
|
||||||
// via `restore_first_arg`. Therefore this shorter lifetime does not leak.
|
// via `restore_first_arg`. Therefore this shorter lifetime does not leak.
|
||||||
self.orig_mut = Some(mem::replace(args.get_mut(0).unwrap(), unsafe {
|
self.orig_mut = Some(mem::replace(&mut args[0], unsafe {
|
||||||
mem::transmute(&mut self.value_copy)
|
mem::transmute(&mut self.value_copy)
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
@ -82,9 +82,7 @@ impl<'a> ArgBackup<'a> {
|
|||||||
/// the current scope. Otherwise it is undefined behavior as the shorter lifetime will leak.
|
/// the current scope. Otherwise it is undefined behavior as the shorter lifetime will leak.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn restore_first_arg(mut self, args: &mut FnCallArgs<'a>) {
|
fn restore_first_arg(mut self, args: &mut FnCallArgs<'a>) {
|
||||||
if let Some(this_pointer) = self.orig_mut.take() {
|
self.orig_mut.take().map(|p| args[0] = p);
|
||||||
args[0] = this_pointer;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -167,12 +165,10 @@ impl Engine {
|
|||||||
allow_dynamic: bool,
|
allow_dynamic: bool,
|
||||||
is_op_assignment: bool,
|
is_op_assignment: bool,
|
||||||
) -> &'s Option<Box<FnResolutionCacheEntry>> {
|
) -> &'s Option<Box<FnResolutionCacheEntry>> {
|
||||||
let mut hash = if let Some(ref args) = args {
|
let mut hash = args.as_ref().map_or(hash_script, |args| {
|
||||||
let hash_params = calc_fn_params_hash(args.iter().map(|a| a.type_id()));
|
let hash_params = calc_fn_params_hash(args.iter().map(|a| a.type_id()));
|
||||||
combine_hashes(hash_script, hash_params)
|
combine_hashes(hash_script, hash_params)
|
||||||
} else {
|
});
|
||||||
hash_script
|
|
||||||
};
|
|
||||||
|
|
||||||
&*state
|
&*state
|
||||||
.fn_resolution_cache_mut()
|
.fn_resolution_cache_mut()
|
||||||
@ -328,7 +324,7 @@ impl Engine {
|
|||||||
let mut backup: Option<ArgBackup> = None;
|
let mut backup: Option<ArgBackup> = None;
|
||||||
if is_ref && func.is_pure() && !args.is_empty() {
|
if is_ref && func.is_pure() && !args.is_empty() {
|
||||||
backup = Some(Default::default());
|
backup = Some(Default::default());
|
||||||
backup.as_mut().unwrap().change_first_arg_to_copy(args);
|
backup.as_mut().map(|bk| bk.change_first_arg_to_copy(args));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run external function
|
// Run external function
|
||||||
@ -344,9 +340,7 @@ impl Engine {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Restore the original reference
|
// Restore the original reference
|
||||||
if let Some(backup) = backup {
|
backup.map(|bk| bk.restore_first_arg(args));
|
||||||
backup.restore_first_arg(args);
|
|
||||||
}
|
|
||||||
|
|
||||||
let result = result.map_err(|err| err.fill_position(pos))?;
|
let result = result.map_err(|err| err.fill_position(pos))?;
|
||||||
|
|
||||||
@ -737,16 +731,16 @@ impl Engine {
|
|||||||
|
|
||||||
// Move captured variables into scope
|
// Move captured variables into scope
|
||||||
#[cfg(not(feature = "no_closure"))]
|
#[cfg(not(feature = "no_closure"))]
|
||||||
if let Some(captured) = _capture_scope {
|
if !func.externals.is_empty() {
|
||||||
if !func.externals.is_empty() {
|
_capture_scope.map(|captured| {
|
||||||
captured
|
captured
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.filter(|(name, _, _)| func.externals.contains(name.as_ref()))
|
.filter(|(name, _, _)| func.externals.contains(name.as_ref()))
|
||||||
.for_each(|(name, value, _)| {
|
.for_each(|(name, value, _)| {
|
||||||
// Consume the scope values.
|
// Consume the scope values.
|
||||||
scope.push_dynamic(name, value);
|
scope.push_dynamic(name, value);
|
||||||
});
|
})
|
||||||
}
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
let result = if _is_method {
|
let result = if _is_method {
|
||||||
@ -782,7 +776,7 @@ impl Engine {
|
|||||||
let mut backup: Option<ArgBackup> = None;
|
let mut backup: Option<ArgBackup> = None;
|
||||||
if is_ref && !args.is_empty() {
|
if is_ref && !args.is_empty() {
|
||||||
backup = Some(Default::default());
|
backup = Some(Default::default());
|
||||||
backup.as_mut().unwrap().change_first_arg_to_copy(args);
|
backup.as_mut().map(|bk| bk.change_first_arg_to_copy(args));
|
||||||
}
|
}
|
||||||
|
|
||||||
let orig_source = state.source.take();
|
let orig_source = state.source.take();
|
||||||
@ -797,9 +791,7 @@ impl Engine {
|
|||||||
state.source = orig_source;
|
state.source = orig_source;
|
||||||
|
|
||||||
// Restore the original reference
|
// Restore the original reference
|
||||||
if let Some(backup) = backup {
|
backup.map(|bk| bk.restore_first_arg(args));
|
||||||
backup.restore_first_arg(args);
|
|
||||||
}
|
|
||||||
|
|
||||||
result?
|
result?
|
||||||
};
|
};
|
||||||
@ -1055,10 +1047,9 @@ impl Engine {
|
|||||||
|
|
||||||
// Propagate the changed value back to the source if necessary
|
// Propagate the changed value back to the source if necessary
|
||||||
if updated {
|
if updated {
|
||||||
target.propagate_changed_value().map_err(|mut err| {
|
target
|
||||||
err.set_position(pos);
|
.propagate_changed_value()
|
||||||
err
|
.map_err(|err| err.fill_position(pos))?;
|
||||||
})?;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok((result, updated))
|
Ok((result, updated))
|
||||||
@ -1467,12 +1458,11 @@ impl Engine {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Clone first argument if the function is not a method after-all
|
// Clone first argument if the function is not a method after-all
|
||||||
if let Some(first) = first_arg_value {
|
if !func.map(|f| f.is_method()).unwrap_or(true) {
|
||||||
if !func.map(|f| f.is_method()).unwrap_or(true) {
|
first_arg_value.map(|first| {
|
||||||
let first_val = args[0].clone();
|
*first = args[0].clone();
|
||||||
args[0] = first;
|
args[0] = first;
|
||||||
*args[0] = first_val;
|
});
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
match func {
|
match func {
|
||||||
|
@ -163,9 +163,7 @@ impl fmt::Debug for Module {
|
|||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
let mut d = f.debug_struct("Module");
|
let mut d = f.debug_struct("Module");
|
||||||
|
|
||||||
if let Some(ref id) = self.id {
|
self.id.as_ref().map(|id| d.field("id", id));
|
||||||
d.field("id", id);
|
|
||||||
}
|
|
||||||
|
|
||||||
if !self.modules.is_empty() {
|
if !self.modules.is_empty() {
|
||||||
d.field(
|
d.field(
|
||||||
@ -621,9 +619,10 @@ impl Module {
|
|||||||
.map(|&name| self.identifiers.get(name))
|
.map(|&name| self.identifiers.get(name))
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
if let Some(f) = self.functions.get_mut(&hash_fn) {
|
self.functions
|
||||||
f.param_names = param_names;
|
.get_mut(&hash_fn)
|
||||||
}
|
.map(|f| f.param_names = param_names);
|
||||||
|
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -504,12 +504,13 @@ fn optimize_stmt(stmt: &mut Stmt, state: &mut State, preserve_result: bool) {
|
|||||||
Stmt::Switch(match_expr, x, _) => {
|
Stmt::Switch(match_expr, x, _) => {
|
||||||
optimize_expr(match_expr, state);
|
optimize_expr(match_expr, state);
|
||||||
x.0.values_mut().for_each(|block| {
|
x.0.values_mut().for_each(|block| {
|
||||||
let condition = if let Some(mut condition) = mem::take(&mut block.0) {
|
let condition = mem::take(&mut block.0).map_or_else(
|
||||||
optimize_expr(&mut condition, state);
|
|| Expr::Unit(Position::NONE),
|
||||||
condition
|
|mut condition| {
|
||||||
} else {
|
optimize_expr(&mut condition, state);
|
||||||
Expr::Unit(Position::NONE)
|
condition
|
||||||
};
|
},
|
||||||
|
);
|
||||||
|
|
||||||
match condition {
|
match condition {
|
||||||
Expr::Unit(_) | Expr::BoolConstant(true, _) => (),
|
Expr::Unit(_) | Expr::BoolConstant(true, _) => (),
|
||||||
|
@ -604,27 +604,13 @@ mod array_functions {
|
|||||||
.call_dynamic(&ctx, None, [x.clone(), y.clone()])
|
.call_dynamic(&ctx, None, [x.clone(), y.clone()])
|
||||||
.ok()
|
.ok()
|
||||||
.and_then(|v| v.as_int().ok())
|
.and_then(|v| v.as_int().ok())
|
||||||
.map(|v| {
|
.map(|v| match v {
|
||||||
if v > 0 {
|
v if v > 0 => Ordering::Greater,
|
||||||
Ordering::Greater
|
v if v < 0 => Ordering::Less,
|
||||||
} else if v < 0 {
|
0 => Ordering::Equal,
|
||||||
Ordering::Less
|
_ => unreachable!(),
|
||||||
} else {
|
|
||||||
Ordering::Equal
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.unwrap_or_else(|| {
|
|
||||||
let x_type_id = x.type_id();
|
|
||||||
let y_type_id = y.type_id();
|
|
||||||
|
|
||||||
if x_type_id > y_type_id {
|
|
||||||
Ordering::Greater
|
|
||||||
} else if x_type_id < y_type_id {
|
|
||||||
Ordering::Less
|
|
||||||
} else {
|
|
||||||
Ordering::Equal
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
|
.unwrap_or_else(|| x.type_id().cmp(&y.type_id()))
|
||||||
});
|
});
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -207,10 +207,8 @@ impl ParseSettings {
|
|||||||
&self,
|
&self,
|
||||||
limit: Option<NonZeroUsize>,
|
limit: Option<NonZeroUsize>,
|
||||||
) -> Result<(), ParseError> {
|
) -> Result<(), ParseError> {
|
||||||
if let Some(limit) = limit {
|
if limit.map(|limit| self.level > limit.get()).unwrap_or(false) {
|
||||||
if self.level > limit.get() {
|
return Err(PERR::ExprTooDeep.into_err(self.pos));
|
||||||
return Err(PERR::ExprTooDeep.into_err(self.pos));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -331,14 +329,15 @@ fn parse_fn_call(
|
|||||||
Token::RightParen => {
|
Token::RightParen => {
|
||||||
eat_token(input, Token::RightParen);
|
eat_token(input, Token::RightParen);
|
||||||
|
|
||||||
let hash = if let Some(ref mut modules) = namespace {
|
let hash = namespace.as_mut().map_or_else(
|
||||||
#[cfg(not(feature = "no_module"))]
|
|| calc_fn_hash(&id, 0),
|
||||||
modules.set_index(state.find_module(&modules[0].name));
|
|modules| {
|
||||||
|
#[cfg(not(feature = "no_module"))]
|
||||||
|
modules.set_index(state.find_module(&modules[0].name));
|
||||||
|
|
||||||
calc_qualified_fn_hash(modules.iter().map(|m| m.name.as_str()), &id, 0)
|
calc_qualified_fn_hash(modules.iter().map(|m| m.name.as_str()), &id, 0)
|
||||||
} else {
|
},
|
||||||
calc_fn_hash(&id, 0)
|
);
|
||||||
};
|
|
||||||
|
|
||||||
let hashes = if is_valid_identifier(id.chars()) {
|
let hashes = if is_valid_identifier(id.chars()) {
|
||||||
FnCallHashes::from_script(hash)
|
FnCallHashes::from_script(hash)
|
||||||
@ -378,14 +377,19 @@ fn parse_fn_call(
|
|||||||
(Token::RightParen, _) => {
|
(Token::RightParen, _) => {
|
||||||
eat_token(input, Token::RightParen);
|
eat_token(input, Token::RightParen);
|
||||||
|
|
||||||
let hash = if let Some(ref mut modules) = namespace {
|
let hash = namespace.as_mut().map_or_else(
|
||||||
#[cfg(not(feature = "no_module"))]
|
|| calc_fn_hash(&id, args.len()),
|
||||||
modules.set_index(state.find_module(&modules[0].name));
|
|modules| {
|
||||||
|
#[cfg(not(feature = "no_module"))]
|
||||||
|
modules.set_index(state.find_module(&modules[0].name));
|
||||||
|
|
||||||
calc_qualified_fn_hash(modules.iter().map(|m| m.name.as_str()), &id, args.len())
|
calc_qualified_fn_hash(
|
||||||
} else {
|
modules.iter().map(|m| m.name.as_str()),
|
||||||
calc_fn_hash(&id, args.len())
|
&id,
|
||||||
};
|
args.len(),
|
||||||
|
)
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
let hashes = if is_valid_identifier(id.chars()) {
|
let hashes = if is_valid_identifier(id.chars()) {
|
||||||
FnCallHashes::from_script(hash)
|
FnCallHashes::from_script(hash)
|
||||||
|
@ -91,21 +91,19 @@ struct FnMetadata {
|
|||||||
|
|
||||||
impl PartialOrd for FnMetadata {
|
impl PartialOrd for FnMetadata {
|
||||||
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
|
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
|
||||||
Some(match self.name.partial_cmp(&other.name).unwrap() {
|
Some(self.cmp(other))
|
||||||
Ordering::Less => Ordering::Less,
|
|
||||||
Ordering::Greater => Ordering::Greater,
|
|
||||||
Ordering::Equal => match self.num_params.partial_cmp(&other.num_params).unwrap() {
|
|
||||||
Ordering::Less => Ordering::Less,
|
|
||||||
Ordering::Greater => Ordering::Greater,
|
|
||||||
Ordering::Equal => self.params.partial_cmp(&other.params).unwrap(),
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Ord for FnMetadata {
|
impl Ord for FnMetadata {
|
||||||
fn cmp(&self, other: &Self) -> Ordering {
|
fn cmp(&self, other: &Self) -> Ordering {
|
||||||
self.partial_cmp(other).unwrap()
|
match self.name.cmp(&other.name) {
|
||||||
|
Ordering::Equal => match self.num_params.cmp(&other.num_params) {
|
||||||
|
Ordering::Equal => self.params.cmp(&other.params),
|
||||||
|
cmp => cmp,
|
||||||
|
},
|
||||||
|
cmp => cmp,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
46
src/token.rs
46
src/token.rs
@ -1251,32 +1251,22 @@ fn scan_block_comment(
|
|||||||
while let Some(c) = stream.get_next() {
|
while let Some(c) = stream.get_next() {
|
||||||
pos.advance();
|
pos.advance();
|
||||||
|
|
||||||
if let Some(comment) = comment {
|
comment.as_mut().map(|comment| comment.push(c));
|
||||||
comment.push(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
match c {
|
match c {
|
||||||
'/' => {
|
'/' => {
|
||||||
if let Some(c2) = stream.peek_next() {
|
stream.peek_next().filter(|&c2| c2 == '*').map(|c2| {
|
||||||
if c2 == '*' {
|
eat_next(stream, pos);
|
||||||
eat_next(stream, pos);
|
comment.as_mut().map(|comment| comment.push(c2));
|
||||||
if let Some(comment) = comment {
|
level += 1;
|
||||||
comment.push(c2);
|
});
|
||||||
}
|
|
||||||
level += 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
'*' => {
|
'*' => {
|
||||||
if let Some(c2) = stream.peek_next() {
|
stream.peek_next().filter(|&c2| c2 == '/').map(|c2| {
|
||||||
if c2 == '/' {
|
eat_next(stream, pos);
|
||||||
eat_next(stream, pos);
|
comment.as_mut().map(|comment| comment.push(c2));
|
||||||
if let Some(comment) = comment {
|
level -= 1;
|
||||||
comment.push(c2);
|
});
|
||||||
}
|
|
||||||
level -= 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
'\n' => pos.new_line(),
|
'\n' => pos.new_line(),
|
||||||
_ => (),
|
_ => (),
|
||||||
@ -1511,12 +1501,10 @@ fn get_next_token_inner(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let num_pos = if let Some(negated_pos) = negated {
|
let num_pos = negated.map_or(start_pos, |negated_pos| {
|
||||||
result.insert(0, '-');
|
result.insert(0, '-');
|
||||||
negated_pos
|
negated_pos
|
||||||
} else {
|
});
|
||||||
start_pos
|
|
||||||
};
|
|
||||||
|
|
||||||
// Parse number
|
// Parse number
|
||||||
return Some((
|
return Some((
|
||||||
@ -1737,9 +1725,7 @@ fn get_next_token_inner(
|
|||||||
pos.new_line();
|
pos.new_line();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if let Some(ref mut comment) = comment {
|
comment.as_mut().map(|comment| comment.push(c));
|
||||||
comment.push(c);
|
|
||||||
}
|
|
||||||
pos.advance();
|
pos.advance();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2198,8 +2184,8 @@ impl<'a> Iterator for TokenIterator<'a> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Run the mapper, if any
|
// Run the mapper, if any
|
||||||
let token = if let Some(map) = self.map {
|
let token = if let Some(map_func) = self.map {
|
||||||
map(token)
|
map_func(token)
|
||||||
} else {
|
} else {
|
||||||
token
|
token
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user