Code style refactor.

This commit is contained in:
Stephen Chung 2021-05-25 10:54:48 +08:00
parent 58d6a88bc4
commit dfea3ed22a
11 changed files with 266 additions and 413 deletions

View File

@ -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);

View File

@ -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();
buf.sort_by(|(a, _), (b, _)| a.cmp(b));
buf.into_iter().for_each(|(key, value)| {
key.hash(state); key.hash(state);
value.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()),

View File

@ -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();

View File

@ -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())
}) })
} }

View File

@ -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,17 +731,17 @@ 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 {
// Method call of script function - map first argument to `this` // Method call of script function - map first argument to `this`
@ -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) {
let first_val = args[0].clone(); first_arg_value.map(|first| {
*first = args[0].clone();
args[0] = first; args[0] = first;
*args[0] = first_val; });
}
} }
match func { match func {

View File

@ -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
} }

View File

@ -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(
|| Expr::Unit(Position::NONE),
|mut condition| {
optimize_expr(&mut condition, state); optimize_expr(&mut condition, state);
condition condition
} else { },
Expr::Unit(Position::NONE) );
};
match condition { match condition {
Expr::Unit(_) | Expr::BoolConstant(true, _) => (), Expr::Unit(_) | Expr::BoolConstant(true, _) => (),

View File

@ -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(())

View File

@ -207,11 +207,9 @@ 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(
|| calc_fn_hash(&id, 0),
|modules| {
#[cfg(not(feature = "no_module"))] #[cfg(not(feature = "no_module"))]
modules.set_index(state.find_module(&modules[0].name)); 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(
|| calc_fn_hash(&id, args.len()),
|modules| {
#[cfg(not(feature = "no_module"))] #[cfg(not(feature = "no_module"))]
modules.set_index(state.find_module(&modules[0].name)); 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)

View File

@ -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,
}
} }
} }

View File

@ -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);
if let Some(comment) = comment { comment.as_mut().map(|comment| comment.push(c2));
comment.push(c2);
}
level += 1; 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);
if let Some(comment) = comment { comment.as_mut().map(|comment| comment.push(c2));
comment.push(c2);
}
level -= 1; 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
}; };