Code style cleanup.

This commit is contained in:
Stephen Chung 2021-06-13 17:41:34 +08:00
parent 8ca24059b1
commit 743d48f44f
8 changed files with 563 additions and 618 deletions

View File

@ -917,7 +917,7 @@ impl StmtBlock {
/// Get the statements of this statements block.
#[inline(always)]
#[must_use]
pub fn statements(&mut self) -> &mut StaticVec<Stmt> {
pub fn statements_mut(&mut self) -> &mut StaticVec<Stmt> {
&mut self.0
}
}
@ -1537,18 +1537,6 @@ impl FnCallHashes {
pub fn is_native_only(&self) -> bool {
self.script.is_none()
}
/// Get the script function hash from this [`FnCallHashes`].
#[inline(always)]
#[must_use]
pub fn script_hash(&self) -> Option<u64> {
self.script
}
/// Get the naive Rust function hash from this [`FnCallHashes`].
#[inline(always)]
#[must_use]
pub fn native_hash(&self) -> u64 {
self.native
}
}
/// _(INTERNALS)_ A function call.

View File

@ -253,10 +253,10 @@ impl<'d, T: Any + Clone> Deref for DynamicReadLock<'d, T> {
#[inline(always)]
fn deref(&self) -> &Self::Target {
match &self.0 {
DynamicReadLockInner::Reference(reference) => *reference,
match self.0 {
DynamicReadLockInner::Reference(ref reference) => *reference,
#[cfg(not(feature = "no_closure"))]
DynamicReadLockInner::Guard(guard) => guard.downcast_ref().expect(
DynamicReadLockInner::Guard(ref guard) => guard.downcast_ref().expect(
"never fails because the read guard was created after checking the data type",
),
}
@ -296,10 +296,10 @@ impl<'d, T: Any + Clone> Deref for DynamicWriteLock<'d, T> {
#[inline(always)]
fn deref(&self) -> &Self::Target {
match &self.0 {
DynamicWriteLockInner::Reference(reference) => *reference,
match self.0 {
DynamicWriteLockInner::Reference(ref reference) => *reference,
#[cfg(not(feature = "no_closure"))]
DynamicWriteLockInner::Guard(guard) => guard.downcast_ref().expect(
DynamicWriteLockInner::Guard(ref guard) => guard.downcast_ref().expect(
"never fails because the write guard was created after checking the data type",
),
}
@ -309,10 +309,10 @@ impl<'d, T: Any + Clone> Deref for DynamicWriteLock<'d, T> {
impl<'d, T: Any + Clone> DerefMut for DynamicWriteLock<'d, T> {
#[inline(always)]
fn deref_mut(&mut self) -> &mut Self::Target {
match &mut self.0 {
DynamicWriteLockInner::Reference(reference) => *reference,
match self.0 {
DynamicWriteLockInner::Reference(ref mut reference) => *reference,
#[cfg(not(feature = "no_closure"))]
DynamicWriteLockInner::Guard(guard) => guard.downcast_mut().expect(
DynamicWriteLockInner::Guard(ref mut guard) => guard.downcast_mut().expect(
"never fails because the write guard was created after checking the data type",
),
}
@ -348,27 +348,27 @@ impl Dynamic {
}
/// Attach arbitrary data to this [`Dynamic`].
pub fn set_tag(&mut self, value: Tag) -> &mut Self {
match &mut self.0 {
Union::Unit(_, tag, _)
| Union::Bool(_, tag, _)
| Union::Str(_, tag, _)
| Union::Char(_, tag, _)
| Union::Int(_, tag, _)
| Union::FnPtr(_, tag, _)
| Union::Variant(_, tag, _) => *tag = value,
match self.0 {
Union::Unit(_, ref mut tag, _)
| Union::Bool(_, ref mut tag, _)
| Union::Str(_, ref mut tag, _)
| Union::Char(_, ref mut tag, _)
| Union::Int(_, ref mut tag, _)
| Union::FnPtr(_, ref mut tag, _)
| Union::Variant(_, ref mut tag, _) => *tag = value,
#[cfg(not(feature = "no_float"))]
Union::Float(_, tag, _) => *tag = value,
Union::Float(_, ref mut tag, _) => *tag = value,
#[cfg(feature = "decimal")]
Union::Decimal(_, tag, _) => *tag = value,
Union::Decimal(_, ref mut tag, _) => *tag = value,
#[cfg(not(feature = "no_index"))]
Union::Array(_, tag, _) => *tag = value,
Union::Array(_, ref mut tag, _) => *tag = value,
#[cfg(not(feature = "no_object"))]
Union::Map(_, tag, _) => *tag = value,
Union::Map(_, ref mut tag, _) => *tag = value,
#[cfg(not(feature = "no_std"))]
Union::TimeStamp(_, tag, _) => *tag = value,
Union::TimeStamp(_, ref mut tag, _) => *tag = value,
#[cfg(not(feature = "no_closure"))]
Union::Shared(_, tag, _) => *tag = value,
Union::Shared(_, ref mut tag, _) => *tag = value,
}
self
}
@ -420,7 +420,7 @@ impl Dynamic {
/// Otherwise, this call panics if the data is currently borrowed for write.
#[must_use]
pub fn type_id(&self) -> TypeId {
match &self.0 {
match self.0 {
Union::Unit(_, _, _) => TypeId::of::<()>(),
Union::Bool(_, _, _) => TypeId::of::<bool>(),
Union::Str(_, _, _) => TypeId::of::<ImmutableString>(),
@ -438,17 +438,15 @@ impl Dynamic {
#[cfg(not(feature = "no_std"))]
Union::TimeStamp(_, _, _) => TypeId::of::<Instant>(),
Union::Variant(value, _, _) => value.as_ref().as_ref().type_id(),
Union::Variant(ref value, _, _) => (***value).type_id(),
#[cfg(not(feature = "no_closure"))]
Union::Shared(cell, _, _) => {
#[cfg(not(feature = "sync"))]
let value = cell.borrow();
#[cfg(feature = "sync")]
let value = cell.read().unwrap();
#[cfg(not(feature = "sync"))]
Union::Shared(ref cell, _, _) => (*cell.borrow()).type_id(),
(*value).type_id()
}
#[cfg(not(feature = "no_closure"))]
#[cfg(feature = "sync")]
Union::Shared(ref cell, _, _) => (*cell.read().unwrap()).type_id(),
}
}
/// Get the name of the type of the value held by this [`Dynamic`].
@ -459,7 +457,7 @@ impl Dynamic {
/// Otherwise, this call panics if the data is currently borrowed for write.
#[must_use]
pub fn type_name(&self) -> &'static str {
match &self.0 {
match self.0 {
Union::Unit(_, _, _) => "()",
Union::Bool(_, _, _) => "bool",
Union::Str(_, _, _) => "string",
@ -477,17 +475,17 @@ impl Dynamic {
#[cfg(not(feature = "no_std"))]
Union::TimeStamp(_, _, _) => "timestamp",
Union::Variant(value, _, _) => value.as_ref().as_ref().type_name(),
Union::Variant(ref value, _, _) => (***value).type_name(),
#[cfg(not(feature = "no_closure"))]
#[cfg(not(feature = "sync"))]
Union::Shared(cell, _, _) => cell
Union::Shared(ref cell, _, _) => cell
.try_borrow()
.map(|v| (*v).type_name())
.unwrap_or("<shared>"),
#[cfg(not(feature = "no_closure"))]
#[cfg(feature = "sync")]
Union::Shared(cell, _, _) => (*cell.read().unwrap()).type_name(),
Union::Shared(ref cell, _, _) => (*cell.read().unwrap()).type_name(),
}
}
}
@ -501,76 +499,67 @@ impl Hash for Dynamic {
fn hash<H: Hasher>(&self, state: &mut H) {
std::mem::discriminant(&self.0).hash(state);
match &self.0 {
match self.0 {
Union::Unit(_, _, _) => ().hash(state),
Union::Bool(b, _, _) => b.hash(state),
Union::Str(s, _, _) => s.hash(state),
Union::Char(c, _, _) => c.hash(state),
Union::Int(i, _, _) => i.hash(state),
Union::Bool(ref b, _, _) => b.hash(state),
Union::Str(ref s, _, _) => s.hash(state),
Union::Char(ref c, _, _) => c.hash(state),
Union::Int(ref i, _, _) => i.hash(state),
#[cfg(not(feature = "no_float"))]
Union::Float(f, _, _) => f.hash(state),
Union::Float(ref f, _, _) => f.hash(state),
#[cfg(not(feature = "no_index"))]
Union::Array(a, _, _) => a.as_ref().hash(state),
Union::Array(ref a, _, _) => a.as_ref().hash(state),
#[cfg(not(feature = "no_object"))]
Union::Map(m, _, _) => m.as_ref().hash(state),
Union::FnPtr(f, _, _) => f.hash(state),
Union::Map(ref m, _, _) => m.as_ref().hash(state),
Union::FnPtr(ref f, _, _) => f.hash(state),
#[cfg(not(feature = "no_closure"))]
Union::Shared(cell, _, _) => {
#[cfg(not(feature = "sync"))]
let value = cell.borrow();
#[cfg(feature = "sync")]
let value = cell.read().unwrap();
#[cfg(not(feature = "sync"))]
Union::Shared(ref cell, _, _) => (*cell.borrow()).hash(state),
(*value).hash(state)
}
#[cfg(not(feature = "no_closure"))]
#[cfg(feature = "sync")]
Union::Shared(ref cell, _, _) => (*cell.read().unwrap()).hash(state),
#[cfg(not(feature = "only_i32"))]
#[cfg(not(feature = "only_i64"))]
Union::Variant(value, _, _) => {
let value = value.as_ref().as_ref();
let _type_id = value.type_id();
let _value_any = value.as_any();
Union::Variant(ref value, _, _) => {
let value_any = (***value).as_any();
let type_id = value_any.type_id();
if _type_id == TypeId::of::<u8>() {
if type_id == TypeId::of::<u8>() {
TypeId::of::<u8>().hash(state);
_value_any.downcast_ref::<u8>().expect(CHECKED).hash(state);
} else if _type_id == TypeId::of::<u16>() {
value_any.downcast_ref::<u8>().expect(CHECKED).hash(state);
} else if type_id == TypeId::of::<u16>() {
TypeId::of::<u16>().hash(state);
_value_any.downcast_ref::<u16>().expect(CHECKED).hash(state);
} else if _type_id == TypeId::of::<u32>() {
value_any.downcast_ref::<u16>().expect(CHECKED).hash(state);
} else if type_id == TypeId::of::<u32>() {
TypeId::of::<u32>().hash(state);
_value_any.downcast_ref::<u32>().expect(CHECKED).hash(state);
} else if _type_id == TypeId::of::<u64>() {
value_any.downcast_ref::<u32>().expect(CHECKED).hash(state);
} else if type_id == TypeId::of::<u64>() {
TypeId::of::<u64>().hash(state);
_value_any.downcast_ref::<u64>().expect(CHECKED).hash(state);
} else if _type_id == TypeId::of::<i8>() {
value_any.downcast_ref::<u64>().expect(CHECKED).hash(state);
} else if type_id == TypeId::of::<i8>() {
TypeId::of::<i8>().hash(state);
_value_any.downcast_ref::<i8>().expect(CHECKED).hash(state);
} else if _type_id == TypeId::of::<i16>() {
value_any.downcast_ref::<i8>().expect(CHECKED).hash(state);
} else if type_id == TypeId::of::<i16>() {
TypeId::of::<i16>().hash(state);
_value_any.downcast_ref::<i16>().expect(CHECKED).hash(state);
} else if _type_id == TypeId::of::<i32>() {
value_any.downcast_ref::<i16>().expect(CHECKED).hash(state);
} else if type_id == TypeId::of::<i32>() {
TypeId::of::<i32>().hash(state);
_value_any.downcast_ref::<i32>().expect(CHECKED).hash(state);
} else if _type_id == TypeId::of::<i64>() {
value_any.downcast_ref::<i32>().expect(CHECKED).hash(state);
} else if type_id == TypeId::of::<i64>() {
TypeId::of::<i64>().hash(state);
_value_any.downcast_ref::<i64>().expect(CHECKED).hash(state);
value_any.downcast_ref::<i64>().expect(CHECKED).hash(state);
}
#[cfg(not(any(target_arch = "wasm32", target_arch = "wasm64")))]
if _type_id == TypeId::of::<u128>() {
if type_id == TypeId::of::<u128>() {
TypeId::of::<u128>().hash(state);
_value_any
.downcast_ref::<u128>()
.expect(CHECKED)
.hash(state);
} else if _type_id == TypeId::of::<i128>() {
value_any.downcast_ref::<u128>().expect(CHECKED).hash(state);
} else if type_id == TypeId::of::<i128>() {
TypeId::of::<i128>().hash(state);
_value_any
.downcast_ref::<i128>()
.expect(CHECKED)
.hash(state);
value_any.downcast_ref::<i128>().expect(CHECKED).hash(state);
}
}
@ -617,31 +606,30 @@ pub(crate) fn map_std_type_name(name: &str) -> &str {
impl fmt::Display for Dynamic {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match &self.0 {
match self.0 {
Union::Unit(_, _, _) => write!(f, ""),
Union::Bool(value, _, _) => fmt::Display::fmt(value, f),
Union::Str(value, _, _) => fmt::Display::fmt(value, f),
Union::Char(value, _, _) => fmt::Display::fmt(value, f),
Union::Int(value, _, _) => fmt::Display::fmt(value, f),
Union::Bool(ref value, _, _) => fmt::Display::fmt(value, f),
Union::Str(ref value, _, _) => fmt::Display::fmt(value, f),
Union::Char(ref value, _, _) => fmt::Display::fmt(value, f),
Union::Int(ref value, _, _) => fmt::Display::fmt(value, f),
#[cfg(not(feature = "no_float"))]
Union::Float(value, _, _) => fmt::Display::fmt(value, f),
Union::Float(ref value, _, _) => fmt::Display::fmt(value, f),
#[cfg(feature = "decimal")]
Union::Decimal(value, _, _) => fmt::Display::fmt(value, f),
Union::Decimal(ref value, _, _) => fmt::Display::fmt(value, f),
#[cfg(not(feature = "no_index"))]
Union::Array(value, _, _) => fmt::Debug::fmt(value, f),
Union::Array(ref value, _, _) => fmt::Debug::fmt(value, f),
#[cfg(not(feature = "no_object"))]
Union::Map(value, _, _) => {
Union::Map(ref value, _, _) => {
f.write_str("#")?;
fmt::Debug::fmt(value, f)
}
Union::FnPtr(value, _, _) => fmt::Display::fmt(value, f),
Union::FnPtr(ref value, _, _) => fmt::Display::fmt(value, f),
#[cfg(not(feature = "no_std"))]
Union::TimeStamp(_, _, _) => f.write_str("<timestamp>"),
Union::Variant(value, _, _) => {
let value = value.as_ref().as_ref();
let _type_id = value.type_id();
let _value_any = value.as_any();
Union::Variant(ref value, _, _) => {
let _value_any = (***value).as_any();
let _type_id = _value_any.type_id();
#[cfg(not(feature = "only_i32"))]
#[cfg(not(feature = "only_i64"))]
@ -677,12 +665,12 @@ impl fmt::Display for Dynamic {
return fmt::Display::fmt(_value_any.downcast_ref::<i128>().expect(CHECKED), f);
}
f.write_str(value.type_name())
f.write_str((***value).type_name())
}
#[cfg(not(feature = "no_closure"))]
#[cfg(not(feature = "sync"))]
Union::Shared(cell, _, _) => {
Union::Shared(ref cell, _, _) => {
if let Ok(v) = cell.try_borrow() {
fmt::Display::fmt(&*v, f)
} else {
@ -691,38 +679,37 @@ impl fmt::Display for Dynamic {
}
#[cfg(not(feature = "no_closure"))]
#[cfg(feature = "sync")]
Union::Shared(cell, _, _) => fmt::Display::fmt(&*cell.read().unwrap(), f),
Union::Shared(ref cell, _, _) => fmt::Display::fmt(&*cell.read().unwrap(), f),
}
}
}
impl fmt::Debug for Dynamic {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match &self.0 {
Union::Unit(value, _, _) => fmt::Debug::fmt(value, f),
Union::Bool(value, _, _) => fmt::Debug::fmt(value, f),
Union::Str(value, _, _) => fmt::Debug::fmt(value, f),
Union::Char(value, _, _) => fmt::Debug::fmt(value, f),
Union::Int(value, _, _) => fmt::Debug::fmt(value, f),
match self.0 {
Union::Unit(ref value, _, _) => fmt::Debug::fmt(value, f),
Union::Bool(ref value, _, _) => fmt::Debug::fmt(value, f),
Union::Str(ref value, _, _) => fmt::Debug::fmt(value, f),
Union::Char(ref value, _, _) => fmt::Debug::fmt(value, f),
Union::Int(ref value, _, _) => fmt::Debug::fmt(value, f),
#[cfg(not(feature = "no_float"))]
Union::Float(value, _, _) => fmt::Debug::fmt(value, f),
Union::Float(ref value, _, _) => fmt::Debug::fmt(value, f),
#[cfg(feature = "decimal")]
Union::Decimal(value, _, _) => fmt::Debug::fmt(value, f),
Union::Decimal(ref value, _, _) => fmt::Debug::fmt(value, f),
#[cfg(not(feature = "no_index"))]
Union::Array(value, _, _) => fmt::Debug::fmt(value, f),
Union::Array(ref value, _, _) => fmt::Debug::fmt(value, f),
#[cfg(not(feature = "no_object"))]
Union::Map(value, _, _) => {
Union::Map(ref value, _, _) => {
f.write_str("#")?;
fmt::Debug::fmt(value, f)
}
Union::FnPtr(value, _, _) => fmt::Debug::fmt(value, f),
Union::FnPtr(ref value, _, _) => fmt::Debug::fmt(value, f),
#[cfg(not(feature = "no_std"))]
Union::TimeStamp(_, _, _) => write!(f, "<timestamp>"),
Union::Variant(value, _, _) => {
let value = value.as_ref().as_ref();
let _type_id = value.type_id();
let _value_any = value.as_any();
Union::Variant(ref value, _, _) => {
let _value_any = (***value).as_any();
let _type_id = _value_any.type_id();
const CHECKED: &str = "never fails because the type was checked";
@ -760,12 +747,12 @@ impl fmt::Debug for Dynamic {
return fmt::Debug::fmt(_value_any.downcast_ref::<i128>().expect(CHECKED), f);
}
f.write_str(value.type_name())
f.write_str((***value).type_name())
}
#[cfg(not(feature = "no_closure"))]
#[cfg(not(feature = "sync"))]
Union::Shared(cell, _, _) => {
Union::Shared(ref cell, _, _) => {
if let Ok(v) = cell.try_borrow() {
write!(f, "{:?} (shared)", *v)
} else {
@ -774,7 +761,7 @@ impl fmt::Debug for Dynamic {
}
#[cfg(not(feature = "no_closure"))]
#[cfg(feature = "sync")]
Union::Shared(cell, _, _) => fmt::Debug::fmt(&*cell.read().unwrap(), f),
Union::Shared(ref cell, _, _) => fmt::Debug::fmt(&*cell.read().unwrap(), f),
}
}
}
@ -921,37 +908,37 @@ impl Dynamic {
}
/// Set the [`AccessMode`] for this [`Dynamic`].
pub(crate) fn set_access_mode(&mut self, typ: AccessMode) -> &mut Self {
match &mut self.0 {
Union::Unit(_, _, access)
| Union::Bool(_, _, access)
| Union::Str(_, _, access)
| Union::Char(_, _, access)
| Union::Int(_, _, access)
| Union::FnPtr(_, _, access)
| Union::Variant(_, _, access) => *access = typ,
match self.0 {
Union::Unit(_, _, ref mut access)
| Union::Bool(_, _, ref mut access)
| Union::Str(_, _, ref mut access)
| Union::Char(_, _, ref mut access)
| Union::Int(_, _, ref mut access)
| Union::FnPtr(_, _, ref mut access)
| Union::Variant(_, _, ref mut access) => *access = typ,
#[cfg(not(feature = "no_float"))]
Union::Float(_, _, access) => *access = typ,
Union::Float(_, _, ref mut access) => *access = typ,
#[cfg(feature = "decimal")]
Union::Decimal(_, _, access) => *access = typ,
Union::Decimal(_, _, ref mut access) => *access = typ,
#[cfg(not(feature = "no_index"))]
Union::Array(a, _, access) => {
Union::Array(ref mut a, _, ref mut access) => {
*access = typ;
a.iter_mut().for_each(|v| {
v.set_access_mode(typ);
});
}
#[cfg(not(feature = "no_object"))]
Union::Map(m, _, access) => {
Union::Map(ref mut m, _, ref mut access) => {
*access = typ;
m.values_mut().for_each(|v| {
v.set_access_mode(typ);
});
}
#[cfg(not(feature = "no_std"))]
Union::TimeStamp(_, _, access) => *access = typ,
Union::TimeStamp(_, _, ref mut access) => *access = typ,
#[cfg(not(feature = "no_closure"))]
Union::Shared(_, _, access) => *access = typ,
Union::Shared(_, _, ref mut access) => *access = typ,
}
self
}
@ -967,17 +954,22 @@ impl Dynamic {
#[cfg(not(feature = "no_closure"))]
match self.0 {
Union::Shared(_, _, ReadOnly) => return true,
Union::Shared(ref cell, _, _) => {
#[cfg(not(feature = "sync"))]
let value = cell.borrow();
#[cfg(feature = "sync")]
let value = cell.read().unwrap();
return match value.access_mode() {
#[cfg(not(feature = "sync"))]
Union::Shared(ref cell, _, _) => {
return match cell.borrow().access_mode() {
ReadWrite => false,
ReadOnly => true,
};
}
}
#[cfg(feature = "sync")]
Union::Shared(ref cell, _, _) => {
return match cell.read().unwrap().access_mode() {
ReadWrite => false,
ReadOnly => true,
}
}
_ => (),
}
@ -989,7 +981,7 @@ impl Dynamic {
/// Can this [`Dynamic`] be hashed?
#[must_use]
pub(crate) fn is_hashable(&self) -> bool {
match &self.0 {
match self.0 {
Union::Unit(_, _, _)
| Union::Bool(_, _, _)
| Union::Str(_, _, _)
@ -1004,14 +996,12 @@ impl Dynamic {
Union::Map(_, _, _) => true,
#[cfg(not(feature = "no_closure"))]
Union::Shared(cell, _, _) => {
#[cfg(not(feature = "sync"))]
let value = cell.borrow();
#[cfg(feature = "sync")]
let value = cell.read().unwrap();
#[cfg(not(feature = "sync"))]
Union::Shared(ref cell, _, _) => cell.borrow().is_hashable(),
value.is_hashable()
}
#[cfg(not(feature = "no_closure"))]
#[cfg(feature = "sync")]
Union::Shared(ref cell, _, _) => cell.read().unwrap().is_hashable(),
_ => false,
}
@ -1388,20 +1378,15 @@ impl Dynamic {
#[inline(always)]
#[must_use]
pub fn flatten_clone(&self) -> Self {
#[cfg(not(feature = "no_closure"))]
match &self.0 {
Union::Shared(cell, _, _) => {
#[cfg(not(feature = "sync"))]
let value = cell.borrow();
#[cfg(feature = "sync")]
let value = cell.read().unwrap();
return value.clone();
}
_ => (),
match self.0 {
#[cfg(not(feature = "no_closure"))]
#[cfg(not(feature = "sync"))]
Union::Shared(ref cell, _, _) => cell.borrow().clone(),
#[cfg(not(feature = "no_closure"))]
#[cfg(feature = "sync")]
Union::Shared(ref cell, _, _) => cell.read().unwrap().clone(),
_ => self.clone(),
}
self.clone()
}
/// Flatten the [`Dynamic`].
///
@ -1412,30 +1397,20 @@ impl Dynamic {
#[inline(always)]
#[must_use]
pub fn flatten(self) -> Self {
#[cfg(not(feature = "no_closure"))]
match self.0 {
Union::Shared(cell, _, _) => {
return crate::fn_native::shared_try_take(cell).map_or_else(
|cell| {
#[cfg(not(feature = "sync"))]
let value = cell.borrow();
#[cfg(feature = "sync")]
let value = cell.read().unwrap();
value.clone()
},
|value| {
#[cfg(not(feature = "sync"))]
return value.into_inner();
#[cfg(feature = "sync")]
return value.into_inner().unwrap();
},
)
}
_ => (),
#[cfg(not(feature = "no_closure"))]
Union::Shared(cell, _, _) => crate::fn_native::shared_try_take(cell).map_or_else(
#[cfg(not(feature = "sync"))]
|cell| cell.borrow().clone(),
#[cfg(feature = "sync")]
|cell| cell.read().unwrap().clone(),
#[cfg(not(feature = "sync"))]
|value| value.into_inner(),
#[cfg(feature = "sync")]
|value| value.into_inner().unwrap(),
),
_ => self,
}
self
}
/// Flatten the [`Dynamic`] in place.
///
@ -1445,26 +1420,20 @@ impl Dynamic {
/// outstanding references, or a cloned copy otherwise.
#[inline(always)]
pub(crate) fn flatten_in_place(&mut self) -> &mut Self {
#[cfg(not(feature = "no_closure"))]
match self.0 {
#[cfg(not(feature = "no_closure"))]
Union::Shared(_, _, _) => match std::mem::take(self).0 {
Union::Shared(cell, _, _) => {
*self = crate::fn_native::shared_try_take(cell).map_or_else(
|cell| {
#[cfg(not(feature = "sync"))]
let value = cell.borrow();
#[cfg(feature = "sync")]
let value = cell.read().unwrap();
value.clone()
},
|value| {
#[cfg(not(feature = "sync"))]
return value.into_inner();
#[cfg(feature = "sync")]
return value.into_inner().unwrap();
},
)
#[cfg(not(feature = "sync"))]
|cell| cell.borrow().clone(),
#[cfg(feature = "sync")]
|cell| cell.read().unwrap().clone(),
#[cfg(not(feature = "sync"))]
|value| value.into_inner(),
#[cfg(feature = "sync")]
|value| value.into_inner().unwrap(),
);
}
_ => unreachable!(),
},
@ -1577,73 +1546,73 @@ impl Dynamic {
// Coded this way in order to maximally leverage potentials for dead-code removal.
if TypeId::of::<T>() == TypeId::of::<INT>() {
return match &self.0 {
Union::Int(value, _, _) => value.as_any().downcast_ref::<T>(),
return match self.0 {
Union::Int(ref value, _, _) => value.as_any().downcast_ref::<T>(),
_ => None,
};
}
#[cfg(not(feature = "no_float"))]
if TypeId::of::<T>() == TypeId::of::<FLOAT>() {
return match &self.0 {
Union::Float(value, _, _) => value.as_ref().as_any().downcast_ref::<T>(),
return match self.0 {
Union::Float(ref value, _, _) => value.as_ref().as_any().downcast_ref::<T>(),
_ => None,
};
}
#[cfg(feature = "decimal")]
if TypeId::of::<T>() == TypeId::of::<Decimal>() {
return match &self.0 {
Union::Decimal(value, _, _) => value.as_ref().as_any().downcast_ref::<T>(),
return match self.0 {
Union::Decimal(ref value, _, _) => value.as_ref().as_any().downcast_ref::<T>(),
_ => None,
};
}
if TypeId::of::<T>() == TypeId::of::<bool>() {
return match &self.0 {
Union::Bool(value, _, _) => value.as_any().downcast_ref::<T>(),
return match self.0 {
Union::Bool(ref value, _, _) => value.as_any().downcast_ref::<T>(),
_ => None,
};
}
if TypeId::of::<T>() == TypeId::of::<ImmutableString>() {
return match &self.0 {
Union::Str(value, _, _) => value.as_any().downcast_ref::<T>(),
return match self.0 {
Union::Str(ref value, _, _) => value.as_any().downcast_ref::<T>(),
_ => None,
};
}
if TypeId::of::<T>() == TypeId::of::<char>() {
return match &self.0 {
Union::Char(value, _, _) => value.as_any().downcast_ref::<T>(),
return match self.0 {
Union::Char(ref value, _, _) => value.as_any().downcast_ref::<T>(),
_ => None,
};
}
#[cfg(not(feature = "no_index"))]
if TypeId::of::<T>() == TypeId::of::<Array>() {
return match &self.0 {
Union::Array(value, _, _) => value.as_ref().as_any().downcast_ref::<T>(),
return match self.0 {
Union::Array(ref value, _, _) => value.as_ref().as_any().downcast_ref::<T>(),
_ => None,
};
}
#[cfg(not(feature = "no_object"))]
if TypeId::of::<T>() == TypeId::of::<Map>() {
return match &self.0 {
Union::Map(value, _, _) => value.as_ref().as_any().downcast_ref::<T>(),
return match self.0 {
Union::Map(ref value, _, _) => value.as_ref().as_any().downcast_ref::<T>(),
_ => None,
};
}
if TypeId::of::<T>() == TypeId::of::<FnPtr>() {
return match &self.0 {
Union::FnPtr(value, _, _) => value.as_ref().as_any().downcast_ref::<T>(),
return match self.0 {
Union::FnPtr(ref value, _, _) => value.as_ref().as_any().downcast_ref::<T>(),
_ => None,
};
}
#[cfg(not(feature = "no_std"))]
if TypeId::of::<T>() == TypeId::of::<Instant>() {
return match &self.0 {
Union::TimeStamp(value, _, _) => value.as_ref().as_any().downcast_ref::<T>(),
return match self.0 {
Union::TimeStamp(ref value, _, _) => value.as_ref().as_any().downcast_ref::<T>(),
_ => None,
};
}
if TypeId::of::<T>() == TypeId::of::<()>() {
return match &self.0 {
Union::Unit(value, _, _) => value.as_any().downcast_ref::<T>(),
return match self.0 {
Union::Unit(ref value, _, _) => value.as_any().downcast_ref::<T>(),
_ => None,
};
}
@ -1651,8 +1620,8 @@ impl Dynamic {
return self.as_any().downcast_ref::<T>();
}
match &self.0 {
Union::Variant(value, _, _) => value.as_ref().as_ref().as_any().downcast_ref::<T>(),
match self.0 {
Union::Variant(ref value, _, _) => (***value).as_any().downcast_ref::<T>(),
#[cfg(not(feature = "no_closure"))]
Union::Shared(_, _, _) => None,
_ => None,
@ -1668,73 +1637,83 @@ impl Dynamic {
// Coded this way in order to maximally leverage potentials for dead-code removal.
if TypeId::of::<T>() == TypeId::of::<INT>() {
return match &mut self.0 {
Union::Int(value, _, _) => value.as_mut_any().downcast_mut::<T>(),
return match self.0 {
Union::Int(ref mut value, _, _) => value.as_mut_any().downcast_mut::<T>(),
_ => None,
};
}
#[cfg(not(feature = "no_float"))]
if TypeId::of::<T>() == TypeId::of::<FLOAT>() {
return match &mut self.0 {
Union::Float(value, _, _) => value.as_mut().as_mut_any().downcast_mut::<T>(),
return match self.0 {
Union::Float(ref mut value, _, _) => {
value.as_mut().as_mut_any().downcast_mut::<T>()
}
_ => None,
};
}
#[cfg(feature = "decimal")]
if TypeId::of::<T>() == TypeId::of::<Decimal>() {
return match &mut self.0 {
Union::Decimal(value, _, _) => value.as_mut().as_mut_any().downcast_mut::<T>(),
return match self.0 {
Union::Decimal(ref mut value, _, _) => {
value.as_mut().as_mut_any().downcast_mut::<T>()
}
_ => None,
};
}
if TypeId::of::<T>() == TypeId::of::<bool>() {
return match &mut self.0 {
Union::Bool(value, _, _) => value.as_mut_any().downcast_mut::<T>(),
return match self.0 {
Union::Bool(ref mut value, _, _) => value.as_mut_any().downcast_mut::<T>(),
_ => None,
};
}
if TypeId::of::<T>() == TypeId::of::<ImmutableString>() {
return match &mut self.0 {
Union::Str(value, _, _) => value.as_mut_any().downcast_mut::<T>(),
return match self.0 {
Union::Str(ref mut value, _, _) => value.as_mut_any().downcast_mut::<T>(),
_ => None,
};
}
if TypeId::of::<T>() == TypeId::of::<char>() {
return match &mut self.0 {
Union::Char(value, _, _) => value.as_mut_any().downcast_mut::<T>(),
return match self.0 {
Union::Char(ref mut value, _, _) => value.as_mut_any().downcast_mut::<T>(),
_ => None,
};
}
#[cfg(not(feature = "no_index"))]
if TypeId::of::<T>() == TypeId::of::<Array>() {
return match &mut self.0 {
Union::Array(value, _, _) => value.as_mut().as_mut_any().downcast_mut::<T>(),
return match self.0 {
Union::Array(ref mut value, _, _) => {
value.as_mut().as_mut_any().downcast_mut::<T>()
}
_ => None,
};
}
#[cfg(not(feature = "no_object"))]
if TypeId::of::<T>() == TypeId::of::<Map>() {
return match &mut self.0 {
Union::Map(value, _, _) => value.as_mut().as_mut_any().downcast_mut::<T>(),
return match self.0 {
Union::Map(ref mut value, _, _) => value.as_mut().as_mut_any().downcast_mut::<T>(),
_ => None,
};
}
if TypeId::of::<T>() == TypeId::of::<FnPtr>() {
return match &mut self.0 {
Union::FnPtr(value, _, _) => value.as_mut().as_mut_any().downcast_mut::<T>(),
return match self.0 {
Union::FnPtr(ref mut value, _, _) => {
value.as_mut().as_mut_any().downcast_mut::<T>()
}
_ => None,
};
}
#[cfg(not(feature = "no_std"))]
if TypeId::of::<T>() == TypeId::of::<Instant>() {
return match &mut self.0 {
Union::TimeStamp(value, _, _) => value.as_mut().as_mut_any().downcast_mut::<T>(),
return match self.0 {
Union::TimeStamp(ref mut value, _, _) => {
value.as_mut().as_mut_any().downcast_mut::<T>()
}
_ => None,
};
}
if TypeId::of::<T>() == TypeId::of::<()>() {
return match &mut self.0 {
Union::Unit(value, _, _) => value.as_mut_any().downcast_mut::<T>(),
return match self.0 {
Union::Unit(ref mut value, _, _) => value.as_mut_any().downcast_mut::<T>(),
_ => None,
};
}
@ -1742,8 +1721,8 @@ impl Dynamic {
return self.as_mut_any().downcast_mut::<T>();
}
match &mut self.0 {
Union::Variant(value, _, _) => value.as_mut().as_mut_any().downcast_mut::<T>(),
match self.0 {
Union::Variant(ref mut value, _, _) => (***value).as_mut_any().downcast_mut::<T>(),
#[cfg(not(feature = "no_closure"))]
Union::Shared(_, _, _) => None,
_ => None,
@ -1898,8 +1877,8 @@ impl Dynamic {
#[cfg(feature = "sync")]
let value = cell.read().unwrap();
match &value.0 {
Union::Str(s, _, _) => Ok(s.clone()),
match value.0 {
Union::Str(ref s, _, _) => Ok(s.clone()),
_ => Err((*value).type_name()),
}
}

View File

@ -1320,9 +1320,9 @@ impl Engine {
// xxx.fn_name(arg_expr_list)
Expr::FnCall(x, pos) if !x.is_qualified() && new_val.is_none() => {
let FnCallExpr { name, hashes, .. } = x.as_ref();
let mut args = idx_val.as_fn_call_args();
let args = &mut idx_val.as_fn_call_args();
self.make_method_call(
mods, state, lib, name, *hashes, target, &mut args, *pos, level,
mods, state, lib, name, *hashes, target, args, *pos, level,
)
}
// xxx.fn_name(...) = ???
@ -1340,11 +1340,11 @@ impl Engine {
new_val.expect("never fails because `new_val` is `Some`");
let index = name.into();
{
let mut val = self.get_indexed_mut(
let val_target = &mut self.get_indexed_mut(
mods, state, lib, target, index, *pos, true, false, level,
)?;
self.eval_op_assignment(
mods, state, lib, op_info, op_pos, &mut val, root, new_val,
mods, state, lib, op_info, op_pos, val_target, root, new_val,
)
.map_err(|err| err.fill_position(new_pos))?;
}
@ -1369,11 +1369,11 @@ impl Engine {
if op_info.is_some() {
let hash = FnCallHashes::from_native(*hash_get);
let mut args = [target.as_mut()];
let args = &mut [target.as_mut()];
let (mut orig_val, _) = self
.exec_fn_call(
mods, state, lib, getter, hash, &mut args, is_ref, true, *pos,
None, level,
mods, state, lib, getter, hash, args, is_ref, true, *pos, None,
level,
)
.or_else(|err| match *err {
// Try an indexer if property does not exist
@ -1413,16 +1413,14 @@ impl Engine {
}
let hash = FnCallHashes::from_native(*hash_set);
let mut args = [target.as_mut(), &mut new_val];
let args = &mut [target.as_mut(), &mut new_val];
self.exec_fn_call(
mods, state, lib, setter, hash, &mut args, is_ref, true, *pos, None,
level,
mods, state, lib, setter, hash, args, is_ref, true, *pos, None, level,
)
.or_else(|err| match *err {
// Try an indexer if property does not exist
EvalAltResult::ErrorDotExpr(_, _) => {
let mut prop = name.into();
let args = &mut [target, &mut prop, &mut new_val];
let args = &mut [target, &mut name.into(), &mut new_val];
let hash_set =
FnCallHashes::from_native(crate::calc_fn_hash(FN_IDX_SET, 3));
self.exec_fn_call(
@ -1443,10 +1441,9 @@ impl Engine {
Expr::Property(x) => {
let ((getter, hash_get), _, (name, pos)) = x.as_ref();
let hash = FnCallHashes::from_native(*hash_get);
let mut args = [target.as_mut()];
let args = &mut [target.as_mut()];
self.exec_fn_call(
mods, state, lib, getter, hash, &mut args, is_ref, true, *pos, None,
level,
mods, state, lib, getter, hash, args, is_ref, true, *pos, None, level,
)
.map_or_else(
|err| match *err {
@ -1471,8 +1468,8 @@ impl Engine {
}
// {xxx:map}.sub_lhs[expr] | {xxx:map}.sub_lhs.expr
Expr::Index(x, x_pos) | Expr::Dot(x, x_pos) if target.is::<Map>() => {
let mut val = match &x.lhs {
Expr::Property(p) => {
let val_target = &mut match x.lhs {
Expr::Property(ref p) => {
let (name, pos) = &p.2;
let index = name.into();
self.get_indexed_mut(
@ -1480,11 +1477,11 @@ impl Engine {
)?
}
// {xxx:map}.fn_name(arg_expr_list)[expr] | {xxx:map}.fn_name(arg_expr_list).expr
Expr::FnCall(x, pos) if !x.is_qualified() => {
Expr::FnCall(ref x, pos) if !x.is_qualified() => {
let FnCallExpr { name, hashes, .. } = x.as_ref();
let mut args = idx_val.as_fn_call_args();
let args = &mut idx_val.as_fn_call_args();
let (val, _) = self.make_method_call(
mods, state, lib, name, *hashes, target, &mut args, *pos, level,
mods, state, lib, name, *hashes, target, args, pos, level,
)?;
val.into()
}
@ -1493,21 +1490,21 @@ impl Engine {
"function call in dot chain should not be namespace-qualified"
),
// Others - syntax error
expr => unreachable!("invalid dot expression: {:?}", expr),
ref expr => unreachable!("invalid dot expression: {:?}", expr),
};
let rhs_chain = match_chain_type(rhs);
self.eval_dot_index_chain_helper(
mods, state, lib, this_ptr, &mut val, root, &x.rhs, idx_values,
mods, state, lib, this_ptr, val_target, root, &x.rhs, idx_values,
rhs_chain, level, new_val,
)
.map_err(|err| err.fill_position(*x_pos))
}
// xxx.sub_lhs[expr] | xxx.sub_lhs.expr
Expr::Index(x, x_pos) | Expr::Dot(x, x_pos) => {
match &x.lhs {
match x.lhs {
// xxx.prop[expr] | xxx.prop.expr
Expr::Property(p) => {
Expr::Property(ref p) => {
let ((getter, hash_get), (setter, hash_set), (name, pos)) =
p.as_ref();
let rhs_chain = match_chain_type(rhs);
@ -1570,8 +1567,8 @@ impl Engine {
|err| match *err {
// Try an indexer if property does not exist
EvalAltResult::ErrorDotExpr(_, _) => {
let mut prop = name.into();
let args = &mut [target.as_mut(), &mut prop, val];
let args =
&mut [target.as_mut(), &mut name.into(), val];
let hash_set = FnCallHashes::from_native(
crate::calc_fn_hash(FN_IDX_SET, 3),
);
@ -1598,12 +1595,12 @@ impl Engine {
Ok((result, may_be_changed))
}
// xxx.fn_name(arg_expr_list)[expr] | xxx.fn_name(arg_expr_list).expr
Expr::FnCall(f, pos) if !f.is_qualified() => {
Expr::FnCall(ref f, pos) if !f.is_qualified() => {
let FnCallExpr { name, hashes, .. } = f.as_ref();
let rhs_chain = match_chain_type(rhs);
let mut args = idx_val.as_fn_call_args();
let args = &mut idx_val.as_fn_call_args();
let (mut val, _) = self.make_method_call(
mods, state, lib, name, *hashes, target, &mut args, *pos, level,
mods, state, lib, name, *hashes, target, args, pos, level,
)?;
let val = &mut val;
let target = &mut val.into();
@ -1612,14 +1609,14 @@ impl Engine {
mods, state, lib, this_ptr, target, root, &x.rhs, idx_values,
rhs_chain, level, new_val,
)
.map_err(|err| err.fill_position(*pos))
.map_err(|err| err.fill_position(pos))
}
// xxx.module::fn_name(...) - syntax error
Expr::FnCall(_, _) => unreachable!(
"function call in dot chain should not be namespace-qualified"
),
// Others - syntax error
expr => unreachable!("invalid dot expression: {:?}", expr),
ref expr => unreachable!("invalid dot expression: {:?}", expr),
}
}
// Syntax error
@ -2109,7 +2106,7 @@ impl Engine {
let namespace = namespace
.as_ref()
.expect("never fails because function call is qualified");
let hash = hashes.native_hash();
let hash = hashes.native;
self.make_qualified_function_call(
scope, mods, state, lib, this_ptr, namespace, name, args, constants, hash,
*pos, level,
@ -2702,7 +2699,7 @@ impl Engine {
let namespace = namespace
.as_ref()
.expect("never fails because function call is qualified");
let hash = hashes.native_hash();
let hash = hashes.native;
self.make_qualified_function_call(
scope, mods, state, lib, this_ptr, namespace, name, args, constants, hash,
*pos, level,

View File

@ -56,91 +56,89 @@ pub fn get_builtin_binary_op_fn(
// One of the operands is a custom type, so it is never built-in
if x.is_variant() || y.is_variant() {
if is_numeric(type1) && is_numeric(type2) {
return if is_numeric(type1) && is_numeric(type2) {
// Disallow comparisons between different numeric types
return None;
}
// If the types are not the same, default to not compare
if type1 != type2 {
return match op {
None
} else if type1 != type2 {
// If the types are not the same, default to not compare
match op {
"!=" => Some(|_, _| Ok(Dynamic::TRUE)),
"==" | ">" | ">=" | "<" | "<=" => Some(|_, _| Ok(Dynamic::FALSE)),
_ => None,
};
}
// Disallow comparisons between the same type
return None;
}
} else {
// Disallow comparisons between the same type
None
};
}
let types_pair = (type1, type2);
macro_rules! impl_op {
($xx:ident $op:tt $yy:ident) => {
return Some(|_, args| {
Some(|_, args| {
let x = &*args[0].read_lock::<$xx>().expect(BUILTIN);
let y = &*args[1].read_lock::<$yy>().expect(BUILTIN);
Ok((x $op y).into())
})
};
($xx:ident . $func:ident ( $yy:ty )) => {
return Some(|_, args| {
Some(|_, args| {
let x = &*args[0].read_lock::<$xx>().expect(BUILTIN);
let y = &*args[1].read_lock::<$yy>().expect(BUILTIN);
Ok(x.$func(y).into())
})
};
($xx:ident . $func:ident ( $yy:ident . $yyy:ident () )) => {
return Some(|_, args| {
Some(|_, args| {
let x = &*args[0].read_lock::<$xx>().expect(BUILTIN);
let y = &*args[1].read_lock::<$yy>().expect(BUILTIN);
Ok(x.$func(y.$yyy()).into())
})
};
($func:ident ( $op:tt )) => {
return Some(|_, args| {
Some(|_, args| {
let (x, y) = $func(args);
Ok((x $op y).into())
})
};
($base:ty => $xx:ident $op:tt $yy:ident) => {
return Some(|_, args| {
Some(|_, args| {
let x = args[0].$xx().expect(BUILTIN) as $base;
let y = args[1].$yy().expect(BUILTIN) as $base;
Ok((x $op y).into())
})
};
($base:ty => $xx:ident . $func:ident ( $yy:ident as $yyy:ty)) => {
return Some(|_, args| {
Some(|_, args| {
let x = args[0].$xx().expect(BUILTIN) as $base;
let y = args[1].$yy().expect(BUILTIN) as $base;
Ok(x.$func(y as $yyy).into())
})
};
($base:ty => $func:ident ( $xx:ident, $yy:ident )) => {
return Some(|_, args| {
Some(|_, args| {
let x = args[0].$xx().expect(BUILTIN) as $base;
let y = args[1].$yy().expect(BUILTIN) as $base;
$func(x, y).map(Into::<Dynamic>::into)
})
};
(from $base:ty => $xx:ident $op:tt $yy:ident) => {
return Some(|_, args| {
Some(|_, args| {
let x = <$base>::from(args[0].$xx().expect(BUILTIN));
let y = <$base>::from(args[1].$yy().expect(BUILTIN));
Ok((x $op y).into())
})
};
(from $base:ty => $xx:ident . $func:ident ( $yy:ident )) => {
return Some(|_, args| {
Some(|_, args| {
let x = <$base>::from(args[0].$xx().expect(BUILTIN));
let y = <$base>::from(args[1].$yy().expect(BUILTIN));
Ok(x.$func(y).into())
})
};
(from $base:ty => $func:ident ( $xx:ident, $yy:ident )) => {
return Some(|_, args| {
Some(|_, args| {
let x = <$base>::from(args[0].$xx().expect(BUILTIN));
let y = <$base>::from(args[1].$yy().expect(BUILTIN));
$func(x, y).map(Into::<Dynamic>::into)
@ -152,7 +150,7 @@ pub fn get_builtin_binary_op_fn(
($x:ty, $xx:ident, $y:ty, $yy:ident) => {
#[cfg(not(feature = "no_float"))]
if types_pair == (TypeId::of::<$x>(), TypeId::of::<$y>()) {
match op {
return match op {
"+" => impl_op!(FLOAT => $xx + $yy),
"-" => impl_op!(FLOAT => $xx - $yy),
"*" => impl_op!(FLOAT => $xx * $yy),
@ -165,8 +163,8 @@ pub fn get_builtin_binary_op_fn(
">=" => impl_op!(FLOAT => $xx >= $yy),
"<" => impl_op!(FLOAT => $xx < $yy),
"<=" => impl_op!(FLOAT => $xx <= $yy),
_ => return None,
}
_ => None,
};
}
};
}
@ -179,41 +177,43 @@ pub fn get_builtin_binary_op_fn(
($x:ty, $xx:ident, $y:ty, $yy:ident) => {
#[cfg(feature = "decimal")]
if types_pair == (TypeId::of::<$x>(), TypeId::of::<$y>()) {
if cfg!(not(feature = "unBUILTIN")) {
use crate::packages::arithmetic::decimal_functions::*;
#[cfg(not(feature = "unchecked"))]
use crate::packages::arithmetic::decimal_functions::*;
match op {
"+" => impl_op!(from Decimal => add($xx, $yy)),
"-" => impl_op!(from Decimal => subtract($xx, $yy)),
"*" => impl_op!(from Decimal => multiply($xx, $yy)),
"/" => impl_op!(from Decimal => divide($xx, $yy)),
"%" => impl_op!(from Decimal => modulo($xx, $yy)),
"**" => impl_op!(from Decimal => power($xx, $yy)),
_ => ()
}
} else {
use rust_decimal::MathematicalOps;
match op {
"+" => impl_op!(from Decimal => $xx + $yy),
"-" => impl_op!(from Decimal => $xx - $yy),
"*" => impl_op!(from Decimal => $xx * $yy),
"/" => impl_op!(from Decimal => $xx / $yy),
"%" => impl_op!(from Decimal => $xx % $yy),
"**" => impl_op!(from Decimal => $xx.powd($yy)),
_ => ()
}
#[cfg(not(feature = "unchecked"))]
match op {
"+" => return impl_op!(from Decimal => add($xx, $yy)),
"-" => return impl_op!(from Decimal => subtract($xx, $yy)),
"*" => return impl_op!(from Decimal => multiply($xx, $yy)),
"/" => return impl_op!(from Decimal => divide($xx, $yy)),
"%" => return impl_op!(from Decimal => modulo($xx, $yy)),
"**" => return impl_op!(from Decimal => power($xx, $yy)),
_ => ()
}
#[cfg(feature = "unchecked")]
use rust_decimal::MathematicalOps;
#[cfg(feature = "unchecked")]
match op {
"+" => return impl_op!(from Decimal => $xx + $yy),
"-" => return impl_op!(from Decimal => $xx - $yy),
"*" => return impl_op!(from Decimal => $xx * $yy),
"/" => return impl_op!(from Decimal => $xx / $yy),
"%" => return impl_op!(from Decimal => $xx % $yy),
"**" => return impl_op!(from Decimal => $xx.powd($yy)),
_ => ()
}
return match op {
"==" => impl_op!(from Decimal => $xx == $yy),
"!=" => impl_op!(from Decimal => $xx != $yy),
">" => impl_op!(from Decimal => $xx > $yy),
">=" => impl_op!(from Decimal => $xx >= $yy),
"<" => impl_op!(from Decimal => $xx < $yy),
"<=" => impl_op!(from Decimal => $xx <= $yy),
_ => return None
}
_ => None
};
}
};
}
@ -234,22 +234,20 @@ pub fn get_builtin_binary_op_fn(
(s1, s2)
}
match op {
"+" => {
return Some(|_, args| {
let x = args[0].as_char().expect(BUILTIN);
let y = &*args[1].read_lock::<ImmutableString>().expect(BUILTIN);
Ok(format!("{}{}", x, y).into())
})
}
return match op {
"+" => Some(|_, args| {
let x = args[0].as_char().expect(BUILTIN);
let y = &*args[1].read_lock::<ImmutableString>().expect(BUILTIN);
Ok(format!("{}{}", x, y).into())
}),
"==" => impl_op!(get_s1s2(==)),
"!=" => impl_op!(get_s1s2(!=)),
">" => impl_op!(get_s1s2(>)),
">=" => impl_op!(get_s1s2(>=)),
"<" => impl_op!(get_s1s2(<)),
"<=" => impl_op!(get_s1s2(<=)),
_ => return None,
}
_ => None,
};
}
// string op char
if types_pair == (TypeId::of::<ImmutableString>(), TypeId::of::<char>()) {
@ -263,36 +261,30 @@ pub fn get_builtin_binary_op_fn(
(s1, s2)
}
match op {
"+" => {
return Some(|_, args| {
let x = &*args[0].read_lock::<ImmutableString>().expect(BUILTIN);
let y = args[1].as_char().expect(BUILTIN);
Ok((x + y).into())
})
}
"-" => {
return Some(|_, args| {
let x = &*args[0].read_lock::<ImmutableString>().expect(BUILTIN);
let y = args[1].as_char().expect(BUILTIN);
Ok((x - y).into())
})
}
return match op {
"+" => Some(|_, args| {
let x = &*args[0].read_lock::<ImmutableString>().expect(BUILTIN);
let y = args[1].as_char().expect(BUILTIN);
Ok((x + y).into())
}),
"-" => Some(|_, args| {
let x = &*args[0].read_lock::<ImmutableString>().expect(BUILTIN);
let y = args[1].as_char().expect(BUILTIN);
Ok((x - y).into())
}),
"==" => impl_op!(get_s1s2(==)),
"!=" => impl_op!(get_s1s2(!=)),
">" => impl_op!(get_s1s2(>)),
">=" => impl_op!(get_s1s2(>=)),
"<" => impl_op!(get_s1s2(<)),
"<=" => impl_op!(get_s1s2(<=)),
OP_CONTAINS => {
return Some(|_, args| {
let s = &*args[0].read_lock::<ImmutableString>().expect(BUILTIN);
let c = args[1].as_char().expect(BUILTIN);
Ok((s.contains(c)).into())
})
}
_ => return None,
}
OP_CONTAINS => Some(|_, args| {
let s = &*args[0].read_lock::<ImmutableString>().expect(BUILTIN);
let c = args[1].as_char().expect(BUILTIN);
Ok((s.contains(c)).into())
}),
_ => None,
};
}
// map op string
@ -300,10 +292,10 @@ pub fn get_builtin_binary_op_fn(
if types_pair == (TypeId::of::<crate::Map>(), TypeId::of::<ImmutableString>()) {
use crate::Map;
match op {
return match op {
OP_CONTAINS => impl_op!(Map.contains_key(ImmutableString.as_str())),
_ => return None,
}
_ => None,
};
}
// Default comparison operators for different types
@ -318,35 +310,36 @@ pub fn get_builtin_binary_op_fn(
// Beyond here, type1 == type2
if type1 == TypeId::of::<INT>() {
if cfg!(not(feature = "unBUILTIN")) {
use crate::packages::arithmetic::arith_basic::INT::functions::*;
#[cfg(not(feature = "unchecked"))]
use crate::packages::arithmetic::arith_basic::INT::functions::*;
match op {
"+" => impl_op!(INT => add(as_int, as_int)),
"-" => impl_op!(INT => subtract(as_int, as_int)),
"*" => impl_op!(INT => multiply(as_int, as_int)),
"/" => impl_op!(INT => divide(as_int, as_int)),
"%" => impl_op!(INT => modulo(as_int, as_int)),
"**" => impl_op!(INT => power(as_int, as_int)),
">>" => impl_op!(INT => shift_right(as_int, as_int)),
"<<" => impl_op!(INT => shift_left(as_int, as_int)),
_ => (),
}
} else {
match op {
"+" => impl_op!(INT => as_int + as_int),
"-" => impl_op!(INT => as_int - as_int),
"*" => impl_op!(INT => as_int * as_int),
"/" => impl_op!(INT => as_int / as_int),
"%" => impl_op!(INT => as_int % as_int),
"**" => impl_op!(INT => as_int.pow(as_int as u32)),
">>" => impl_op!(INT => as_int >> as_int),
"<<" => impl_op!(INT => as_int << as_int),
_ => (),
}
#[cfg(not(feature = "unchecked"))]
match op {
"+" => return impl_op!(INT => add(as_int, as_int)),
"-" => return impl_op!(INT => subtract(as_int, as_int)),
"*" => return impl_op!(INT => multiply(as_int, as_int)),
"/" => return impl_op!(INT => divide(as_int, as_int)),
"%" => return impl_op!(INT => modulo(as_int, as_int)),
"**" => return impl_op!(INT => power(as_int, as_int)),
">>" => return impl_op!(INT => shift_right(as_int, as_int)),
"<<" => return impl_op!(INT => shift_left(as_int, as_int)),
_ => (),
}
#[cfg(feature = "unchecked")]
match op {
"+" => return impl_op!(INT => as_int + as_int),
"-" => return impl_op!(INT => as_int - as_int),
"*" => return impl_op!(INT => as_int * as_int),
"/" => return impl_op!(INT => as_int / as_int),
"%" => return impl_op!(INT => as_int % as_int),
"**" => return impl_op!(INT => as_int.pow(as_int as u32)),
">>" => return impl_op!(INT => as_int >> as_int),
"<<" => return impl_op!(INT => as_int << as_int),
_ => (),
}
return match op {
"==" => impl_op!(INT => as_int == as_int),
"!=" => impl_op!(INT => as_int != as_int),
">" => impl_op!(INT => as_int > as_int),
@ -356,12 +349,12 @@ pub fn get_builtin_binary_op_fn(
"&" => impl_op!(INT => as_int & as_int),
"|" => impl_op!(INT => as_int | as_int),
"^" => impl_op!(INT => as_int ^ as_int),
_ => return None,
}
_ => None,
};
}
if type1 == TypeId::of::<bool>() {
match op {
return match op {
"==" => impl_op!(bool => as_bool == as_bool),
"!=" => impl_op!(bool => as_bool != as_bool),
">" => impl_op!(bool => as_bool > as_bool),
@ -371,12 +364,12 @@ pub fn get_builtin_binary_op_fn(
"&" => impl_op!(bool => as_bool & as_bool),
"|" => impl_op!(bool => as_bool | as_bool),
"^" => impl_op!(bool => as_bool ^ as_bool),
_ => return None,
}
_ => None,
};
}
if type1 == TypeId::of::<ImmutableString>() {
match op {
return match op {
"+" => impl_op!(ImmutableString + ImmutableString),
"-" => impl_op!(ImmutableString - ImmutableString),
"==" => impl_op!(ImmutableString == ImmutableString),
@ -385,42 +378,38 @@ pub fn get_builtin_binary_op_fn(
">=" => impl_op!(ImmutableString >= ImmutableString),
"<" => impl_op!(ImmutableString < ImmutableString),
"<=" => impl_op!(ImmutableString <= ImmutableString),
OP_CONTAINS => {
return Some(|_, args| {
let s1 = &*args[0].read_lock::<ImmutableString>().expect(BUILTIN);
let s2 = &*args[1].read_lock::<ImmutableString>().expect(BUILTIN);
Ok((s1.contains(s2.as_str())).into())
})
}
_ => return None,
}
OP_CONTAINS => Some(|_, args| {
let s1 = &*args[0].read_lock::<ImmutableString>().expect(BUILTIN);
let s2 = &*args[1].read_lock::<ImmutableString>().expect(BUILTIN);
Ok((s1.contains(s2.as_str())).into())
}),
_ => None,
};
}
if type1 == TypeId::of::<char>() {
match op {
"+" => {
return Some(|_, args| {
let x = args[0].as_char().expect(BUILTIN);
let y = args[1].as_char().expect(BUILTIN);
Ok(format!("{}{}", x, y).into())
})
}
return match op {
"+" => Some(|_, args| {
let x = args[0].as_char().expect(BUILTIN);
let y = args[1].as_char().expect(BUILTIN);
Ok(format!("{}{}", x, y).into())
}),
"==" => impl_op!(char => as_char == as_char),
"!=" => impl_op!(char => as_char != as_char),
">" => impl_op!(char => as_char > as_char),
">=" => impl_op!(char => as_char >= as_char),
"<" => impl_op!(char => as_char < as_char),
"<=" => impl_op!(char => as_char <= as_char),
_ => return None,
}
_ => None,
};
}
if type1 == TypeId::of::<()>() {
match op {
"==" => return Some(|_, _| Ok(Dynamic::TRUE)),
"!=" | ">" | ">=" | "<" | "<=" => return Some(|_, _| Ok(Dynamic::FALSE)),
_ => return None,
}
return match op {
"==" => Some(|_, _| Ok(Dynamic::TRUE)),
"!=" | ">" | ">=" | "<" | "<=" => Some(|_, _| Ok(Dynamic::FALSE)),
_ => None,
};
}
None
@ -444,53 +433,53 @@ pub fn get_builtin_op_assignment_fn(
macro_rules! impl_op {
($x:ty = x $op:tt $yy:ident) => {
return Some(|_, args| {
Some(|_, args| {
let x = args[0].$yy().expect(BUILTIN);
let y = args[1].$yy().expect(BUILTIN) as $x;
Ok((*args[0].write_lock::<$x>().expect(BUILTIN) = x $op y).into())
})
};
($x:ident $op:tt $yy:ident) => {
return Some(|_, args| {
Some(|_, args| {
let y = args[1].$yy().expect(BUILTIN) as $x;
Ok((*args[0].write_lock::<$x>().expect(BUILTIN) $op y).into())
})
};
($x:ident $op:tt $yy:ident as $yyy:ty) => {
return Some(|_, args| {
Some(|_, args| {
let y = args[1].$yy().expect(BUILTIN) as $yyy;
Ok((*args[0].write_lock::<$x>().expect(BUILTIN) $op y).into())
})
};
($x:ty => $xx:ident . $func:ident ( $yy:ident as $yyy:ty )) => {
return Some(|_, args| {
Some(|_, args| {
let x = args[0].$xx().expect(BUILTIN);
let y = args[1].$yy().expect(BUILTIN) as $x;
Ok((*args[0].write_lock::<$x>().expect(BUILTIN) = x.$func(y as $yyy)).into())
})
};
($x:ty => $func:ident ( $xx:ident, $yy:ident )) => {
return Some(|_, args| {
Some(|_, args| {
let x = args[0].$xx().expect(BUILTIN);
let y = args[1].$yy().expect(BUILTIN) as $x;
Ok((*args[0].write_lock().expect(BUILTIN) = $func(x, y)?).into())
})
};
(from $x:ident $op:tt $yy:ident) => {
return Some(|_, args| {
Some(|_, args| {
let y = <$x>::from(args[1].$yy().expect(BUILTIN));
Ok((*args[0].write_lock::<$x>().expect(BUILTIN) $op y).into())
})
};
(from $x:ty => $xx:ident . $func:ident ( $yy:ident )) => {
return Some(|_, args| {
Some(|_, args| {
let x = args[0].$xx().expect(BUILTIN);
let y = <$x>::from(args[1].$yy().expect(BUILTIN));
Ok((*args[0].write_lock::<$x>().expect(BUILTIN) = x.$func(y)).into())
})
};
(from $x:ty => $func:ident ( $xx:ident, $yy:ident )) => {
return Some(|_, args| {
Some(|_, args| {
let x = args[0].$xx().expect(BUILTIN);
let y = <$x>::from(args[1].$yy().expect(BUILTIN));
Ok((*args[0].write_lock().expect(BUILTIN) = $func(x, y)?).into())
@ -502,15 +491,15 @@ pub fn get_builtin_op_assignment_fn(
($x:ident, $xx:ident, $y:ty, $yy:ident) => {
#[cfg(not(feature = "no_float"))]
if types_pair == (TypeId::of::<$x>(), TypeId::of::<$y>()) {
match op {
return match op {
"+=" => impl_op!($x += $yy),
"-=" => impl_op!($x -= $yy),
"*=" => impl_op!($x *= $yy),
"/=" => impl_op!($x /= $yy),
"%=" => impl_op!($x %= $yy),
"**=" => impl_op!($x => $xx.powf($yy as $x)),
_ => return None,
}
_ => None,
};
}
}
}
@ -522,31 +511,33 @@ pub fn get_builtin_op_assignment_fn(
($x:ident, $xx:ident, $y:ty, $yy:ident) => {
#[cfg(feature = "decimal")]
if types_pair == (TypeId::of::<$x>(), TypeId::of::<$y>()) {
if cfg!(not(feature = "unBUILTIN")) {
use crate::packages::arithmetic::decimal_functions::*;
#[cfg(not(feature = "unchecked"))]
use crate::packages::arithmetic::decimal_functions::*;
match op {
"+=" => impl_op!(from $x => add($xx, $yy)),
"-=" => impl_op!(from $x => subtract($xx, $yy)),
"*=" => impl_op!(from $x => multiply($xx, $yy)),
"/=" => impl_op!(from $x => divide($xx, $yy)),
"%=" => impl_op!(from $x => modulo($xx, $yy)),
"**=" => impl_op!(from $x => power($xx, $yy)),
_ => return None,
}
} else {
use rust_decimal::MathematicalOps;
#[cfg(not(feature = "unchecked"))]
return match op {
"+=" => impl_op!(from $x => add($xx, $yy)),
"-=" => impl_op!(from $x => subtract($xx, $yy)),
"*=" => impl_op!(from $x => multiply($xx, $yy)),
"/=" => impl_op!(from $x => divide($xx, $yy)),
"%=" => impl_op!(from $x => modulo($xx, $yy)),
"**=" => impl_op!(from $x => power($xx, $yy)),
_ => None,
};
match op {
"+=" => impl_op!(from $x += $yy),
"-=" => impl_op!(from $x -= $yy),
"*=" => impl_op!(from $x *= $yy),
"/=" => impl_op!(from $x /= $yy),
"%=" => impl_op!(from $x %= $yy),
"**=" => impl_op!(from $x => $xx.powd($yy)),
_ => return None,
}
}
#[cfg(feature = "unchecked")]
use rust_decimal::MathematicalOps;
#[cfg(feature = "unchecked")]
return match op {
"+=" => impl_op!(from $x += $yy),
"-=" => impl_op!(from $x -= $yy),
"*=" => impl_op!(from $x *= $yy),
"/=" => impl_op!(from $x /= $yy),
"%=" => impl_op!(from $x %= $yy),
"**=" => impl_op!(from $x => $xx.powd($yy)),
_ => None,
};
}
};
}
@ -556,31 +547,29 @@ pub fn get_builtin_op_assignment_fn(
// string op= char
if types_pair == (TypeId::of::<ImmutableString>(), TypeId::of::<char>()) {
match op {
return match op {
"+=" => impl_op!(ImmutableString += as_char as char),
"-=" => impl_op!(ImmutableString -= as_char as char),
_ => return None,
}
_ => None,
};
}
// char op= string
if types_pair == (TypeId::of::<char>(), TypeId::of::<ImmutableString>()) {
match op {
"+=" => {
return Some(|_, args| {
let mut ch = args[0].as_char().expect(BUILTIN).to_string();
ch.push_str(
args[1]
.read_lock::<ImmutableString>()
.expect(BUILTIN)
.as_str(),
);
return match op {
"+=" => Some(|_, args| {
let mut ch = args[0].as_char().expect(BUILTIN).to_string();
ch.push_str(
args[1]
.read_lock::<ImmutableString>()
.expect(BUILTIN)
.as_str(),
);
let mut x = args[0].write_lock::<Dynamic>().expect(BUILTIN);
Ok((*x = ch.into()).into())
})
}
_ => return None,
}
let mut x = args[0].write_lock::<Dynamic>().expect(BUILTIN);
Ok((*x = ch.into()).into())
}),
_ => None,
};
}
// No built-in op-assignments for different types.
@ -590,83 +579,78 @@ pub fn get_builtin_op_assignment_fn(
// Beyond here, type1 == type2
if type1 == TypeId::of::<INT>() {
if cfg!(not(feature = "unBUILTIN")) {
use crate::packages::arithmetic::arith_basic::INT::functions::*;
#[cfg(not(feature = "unchecked"))]
use crate::packages::arithmetic::arith_basic::INT::functions::*;
match op {
"+=" => impl_op!(INT => add(as_int, as_int)),
"-=" => impl_op!(INT => subtract(as_int, as_int)),
"*=" => impl_op!(INT => multiply(as_int, as_int)),
"/=" => impl_op!(INT => divide(as_int, as_int)),
"%=" => impl_op!(INT => modulo(as_int, as_int)),
"**=" => impl_op!(INT => power(as_int, as_int)),
">>=" => impl_op!(INT => shift_right(as_int, as_int)),
"<<=" => impl_op!(INT => shift_left(as_int, as_int)),
_ => (),
}
} else {
match op {
"+=" => impl_op!(INT += as_int),
"-=" => impl_op!(INT -= as_int),
"*=" => impl_op!(INT *= as_int),
"/=" => impl_op!(INT /= as_int),
"%=" => impl_op!(INT %= as_int),
"**=" => impl_op!(INT => as_int.pow(as_int as u32)),
">>=" => impl_op!(INT >>= as_int),
"<<=" => impl_op!(INT <<= as_int),
_ => (),
}
#[cfg(not(feature = "unchecked"))]
match op {
"+=" => return impl_op!(INT => add(as_int, as_int)),
"-=" => return impl_op!(INT => subtract(as_int, as_int)),
"*=" => return impl_op!(INT => multiply(as_int, as_int)),
"/=" => return impl_op!(INT => divide(as_int, as_int)),
"%=" => return impl_op!(INT => modulo(as_int, as_int)),
"**=" => return impl_op!(INT => power(as_int, as_int)),
">>=" => return impl_op!(INT => shift_right(as_int, as_int)),
"<<=" => return impl_op!(INT => shift_left(as_int, as_int)),
_ => (),
}
#[cfg(feature = "unchecked")]
match op {
"+=" => return impl_op!(INT += as_int),
"-=" => return impl_op!(INT -= as_int),
"*=" => return impl_op!(INT *= as_int),
"/=" => return impl_op!(INT /= as_int),
"%=" => return impl_op!(INT %= as_int),
"**=" => return impl_op!(INT => as_int.pow(as_int as u32)),
">>=" => return impl_op!(INT >>= as_int),
"<<=" => return impl_op!(INT <<= as_int),
_ => (),
}
return match op {
"&=" => impl_op!(INT &= as_int),
"|=" => impl_op!(INT |= as_int),
"^=" => impl_op!(INT ^= as_int),
_ => (),
}
_ => None,
};
}
if type1 == TypeId::of::<bool>() {
match op {
return match op {
"&=" => impl_op!(bool = x && as_bool),
"|=" => impl_op!(bool = x || as_bool),
_ => return None,
}
_ => None,
};
}
if type1 == TypeId::of::<char>() {
match op {
"+=" => {
return Some(|_, args| {
let y = args[1].as_char().expect(BUILTIN);
let mut x = args[0].write_lock::<Dynamic>().expect(BUILTIN);
Ok((*x = format!("{}{}", *x, y).into()).into())
})
}
_ => return None,
}
return match op {
"+=" => Some(|_, args| {
let y = args[1].as_char().expect(BUILTIN);
let mut x = args[0].write_lock::<Dynamic>().expect(BUILTIN);
Ok((*x = format!("{}{}", *x, y).into()).into())
}),
_ => None,
};
}
if type1 == TypeId::of::<ImmutableString>() {
match op {
"+=" => {
return Some(|_, args| {
let (first, second) = args.split_first_mut().expect(BUILTIN);
let mut x = first.write_lock::<ImmutableString>().expect(BUILTIN);
let y = &*second[0].read_lock::<ImmutableString>().expect(BUILTIN);
Ok((*x += y).into())
})
}
"-=" => {
return Some(|_, args| {
let (first, second) = args.split_first_mut().expect(BUILTIN);
let mut x = first.write_lock::<ImmutableString>().expect(BUILTIN);
let y = &*second[0].read_lock::<ImmutableString>().expect(BUILTIN);
Ok((*x -= y).into())
})
}
_ => return None,
}
return match op {
"+=" => Some(|_, args| {
let (first, second) = args.split_first_mut().expect(BUILTIN);
let mut x = first.write_lock::<ImmutableString>().expect(BUILTIN);
let y = &*second[0].read_lock::<ImmutableString>().expect(BUILTIN);
Ok((*x += y).into())
}),
"-=" => Some(|_, args| {
let (first, second) = args.split_first_mut().expect(BUILTIN);
let mut x = first.write_lock::<ImmutableString>().expect(BUILTIN);
let y = &*second[0].read_lock::<ImmutableString>().expect(BUILTIN);
Ok((*x -= y).into())
}),
_ => None,
};
}
None

View File

@ -618,7 +618,7 @@ impl Engine {
state: &mut State,
lib: &[&Module],
fn_name: &str,
hash: FnCallHashes,
hashes: FnCallHashes,
args: &mut FnCallArgs,
is_ref: bool,
_is_method: bool,
@ -689,7 +689,7 @@ impl Engine {
// Scripted function call?
#[cfg(not(feature = "no_function"))]
let hash_script = hash.script_hash();
let hash_script = hashes.script;
#[cfg(not(feature = "no_function"))]
if let Some(f) = hash_script.and_then(|hash| {
@ -779,7 +779,7 @@ impl Engine {
}
// Native function call
let hash = hash.native_hash();
let hash = hashes.native;
self.call_native_fn(mods, state, lib, fn_name, hash, args, is_ref, false, pos)
}

View File

@ -444,11 +444,11 @@ fn optimize_stmt(stmt: &mut Stmt, state: &mut State, preserve_result: bool) {
// if expr { if_block } else { else_block }
Stmt::If(condition, x, _) => {
optimize_expr(condition, state, false);
let if_block = mem::take(x.0.statements()).into_vec();
*x.0.statements() =
let if_block = mem::take(x.0.statements_mut()).into_vec();
*x.0.statements_mut() =
optimize_stmt_block(if_block, state, preserve_result, true, false).into();
let else_block = mem::take(x.1.statements()).into_vec();
*x.1.statements() =
let else_block = mem::take(x.1.statements_mut()).into_vec();
*x.1.statements_mut() =
optimize_stmt_block(else_block, state, preserve_result, true, false).into();
}
@ -520,8 +520,8 @@ fn optimize_stmt(stmt: &mut Stmt, state: &mut State, preserve_result: bool) {
_ => {
block.0 = Some(condition);
*block.1.statements() = optimize_stmt_block(
mem::take(block.1.statements()).into_vec(),
*block.1.statements_mut() = optimize_stmt_block(
mem::take(block.1.statements_mut()).into_vec(),
state,
preserve_result,
true,
@ -541,8 +541,8 @@ fn optimize_stmt(stmt: &mut Stmt, state: &mut State, preserve_result: bool) {
x.0.remove(&key);
}
let def_block = mem::take(x.1.statements()).into_vec();
*x.1.statements() =
let def_block = mem::take(x.1.statements_mut()).into_vec();
*x.1.statements_mut() =
optimize_stmt_block(def_block, state, preserve_result, true, false).into();
}
@ -554,8 +554,8 @@ fn optimize_stmt(stmt: &mut Stmt, state: &mut State, preserve_result: bool) {
// while expr { block }
Stmt::While(condition, body, _) => {
optimize_expr(condition, state, false);
let block = mem::take(body.statements()).into_vec();
*body.statements() = optimize_stmt_block(block, state, false, true, false).into();
let block = mem::take(body.statements_mut()).into_vec();
*body.statements_mut() = optimize_stmt_block(block, state, false, true, false).into();
if body.len() == 1 {
match body[0] {
@ -582,7 +582,7 @@ fn optimize_stmt(stmt: &mut Stmt, state: &mut State, preserve_result: bool) {
| Stmt::Do(body, Expr::BoolConstant(false, _), true, _) => {
state.set_dirty();
let block_pos = body.position();
let block = mem::take(body.statements()).into_vec();
let block = mem::take(body.statements_mut()).into_vec();
*stmt = Stmt::Block(
optimize_stmt_block(block, state, false, true, false).into_boxed_slice(),
block_pos,
@ -591,14 +591,14 @@ fn optimize_stmt(stmt: &mut Stmt, state: &mut State, preserve_result: bool) {
// do { block } while|until expr
Stmt::Do(body, condition, _, _) => {
optimize_expr(condition, state, false);
let block = mem::take(body.statements()).into_vec();
*body.statements() = optimize_stmt_block(block, state, false, true, false).into();
let block = mem::take(body.statements_mut()).into_vec();
*body.statements_mut() = optimize_stmt_block(block, state, false, true, false).into();
}
// for id in expr { block }
Stmt::For(iterable, x, _) => {
optimize_expr(iterable, state, false);
let body = mem::take(x.2.statements()).into_vec();
*x.2.statements() = optimize_stmt_block(body, state, false, true, false).into();
let body = mem::take(x.2.statements_mut()).into_vec();
*x.2.statements_mut() = optimize_stmt_block(body, state, false, true, false).into();
}
// let id = expr;
Stmt::Let(expr, _, _, _) => optimize_expr(expr, state, false),
@ -636,10 +636,12 @@ fn optimize_stmt(stmt: &mut Stmt, state: &mut State, preserve_result: bool) {
}
// try { try_block } catch ( var ) { catch_block }
Stmt::TryCatch(x, _, _) => {
let try_block = mem::take(x.0.statements()).into_vec();
*x.0.statements() = optimize_stmt_block(try_block, state, false, true, false).into();
let catch_block = mem::take(x.2.statements()).into_vec();
*x.2.statements() = optimize_stmt_block(catch_block, state, false, true, false).into();
let try_block = mem::take(x.0.statements_mut()).into_vec();
*x.0.statements_mut() =
optimize_stmt_block(try_block, state, false, true, false).into();
let catch_block = mem::take(x.2.statements_mut()).into_vec();
*x.2.statements_mut() =
optimize_stmt_block(catch_block, state, false, true, false).into();
}
// func(...)
Stmt::Expr(expr @ Expr::FnCall(_, _)) => {
@ -686,7 +688,7 @@ fn optimize_expr(expr: &mut Expr, state: &mut State, _chaining: bool) {
Expr::Stmt(x) if x.is_empty() => { state.set_dirty(); *expr = Expr::Unit(x.position()) }
// { stmt; ... } - do not count promotion as dirty because it gets turned back into an array
Expr::Stmt(x) => {
*x.statements() = optimize_stmt_block(mem::take(x.statements()).into_vec(), state, true, true, false).into();
*x.statements_mut() = optimize_stmt_block(mem::take(x.statements_mut()).into_vec(), state, true, true, false).into();
// { Stmt(Expr) } - promote
match x.as_mut().as_mut() {
@ -948,7 +950,7 @@ fn optimize_expr(expr: &mut Expr, state: &mut State, _chaining: bool) {
let arg_types: StaticVec<_> = arg_values.iter().map(Dynamic::type_id).collect();
// Search for overloaded operators (can override built-in).
if !has_native_fn(state, x.hashes.native_hash(), arg_types.as_ref()) {
if !has_native_fn(state, x.hashes.native, arg_types.as_ref()) {
if let Some(mut result) = get_builtin_binary_op_fn(x.name.as_ref(), &arg_values[0], &arg_values[1])
.and_then(|f| {
let ctx = (state.engine, x.name.as_ref(), state.lib).into();
@ -1136,9 +1138,9 @@ pub fn optimize_into_ast(
// Optimize the function body
let state = &mut State::new(engine, lib2, level);
let body = mem::take(fn_def.body.statements()).into_vec();
let body = mem::take(fn_def.body.statements_mut()).into_vec();
*fn_def.body.statements() =
*fn_def.body.statements_mut() =
optimize_stmt_block(body, state, true, true, true).into();
fn_def

View File

@ -287,9 +287,8 @@ def_package!(crate:BasicIteratorPackage:"Basic range iterators.", lib, {
{
reg_range!(lib | "range" => i8, u8, i16, u16, i32, u32, i64, u64);
if cfg!(not(target_arch = "wasm32")) {
reg_range!(lib | "range" => i128, u128);
}
#[cfg(not(target_arch = "wasm32"))]
reg_range!(lib | "range" => i128, u128);
}
reg_range!(lib | step "range" => INT);
@ -299,9 +298,8 @@ def_package!(crate:BasicIteratorPackage:"Basic range iterators.", lib, {
{
reg_range!(lib | step "range" => i8, u8, i16, u16, i32, u32, i64, u64);
if cfg!(not(target_arch = "wasm32")) {
reg_range!(lib | step "range" => i128, u128);
}
#[cfg(not(target_arch = "wasm32"))]
reg_range!(lib | step "range" => i128, u128);
}
#[cfg(not(feature = "no_float"))]

View File

@ -478,7 +478,7 @@ fn parse_index_chain(
let idx_expr = parse_expr(input, state, lib, settings.level_up())?;
// Check type of indexing - must be integer or string
match &idx_expr {
match idx_expr {
Expr::IntegerConstant(_, pos) => match lhs {
Expr::IntegerConstant(_, _)
| Expr::Array(_, _)
@ -489,7 +489,7 @@ fn parse_index_chain(
return Err(PERR::MalformedIndexExpr(
"Object map access expects string index, not a number".into(),
)
.into_err(*pos))
.into_err(pos))
}
#[cfg(not(feature = "no_float"))]
@ -1314,14 +1314,14 @@ fn parse_primary(
// Cache the hash key for namespace-qualified variables
match root_expr {
Expr::Variable(_, _, ref mut x) if x.1.is_some() => Some(x),
Expr::Index(ref mut x, _) | Expr::Dot(ref mut x, _) => match &mut x.lhs {
Expr::Variable(_, _, x) if x.1.is_some() => Some(x),
Expr::Variable(_, _, ref mut x) if x.1.is_some() => Some(x.as_mut()),
Expr::Index(ref mut x, _) | Expr::Dot(ref mut x, _) => match x.lhs {
Expr::Variable(_, _, ref mut x) if x.1.is_some() => Some(x.as_mut()),
_ => None,
},
_ => None,
}
.map(|x| match x.as_mut() {
.map(|x| match x {
(_, Some((hash, namespace)), name) => {
*hash = calc_qualified_fn_hash(namespace.iter().map(|v| v.name.as_str()), name, 0);
@ -1467,17 +1467,17 @@ fn make_assignment_stmt<'a>(
let op_info = op.map(|v| OpAssignment::new(v));
match &lhs {
match lhs {
// const_expr = rhs
expr if expr.is_constant() => {
ref expr if expr.is_constant() => {
Err(PERR::AssignmentToConstant("".into()).into_err(lhs.position()))
}
// var (non-indexed) = rhs
Expr::Variable(None, _, x) if x.0.is_none() => {
Expr::Variable(None, _, ref x) if x.0.is_none() => {
Ok(Stmt::Assignment(Box::new((lhs, op_info, rhs)), op_pos))
}
// var (indexed) = rhs
Expr::Variable(i, var_pos, x) => {
Expr::Variable(i, var_pos, ref x) => {
let (index, _, name) = x.as_ref();
let index = i.map_or_else(
|| {
@ -1495,20 +1495,20 @@ fn make_assignment_stmt<'a>(
}
// Constant values cannot be assigned to
AccessMode::ReadOnly => {
Err(PERR::AssignmentToConstant(name.to_string()).into_err(*var_pos))
Err(PERR::AssignmentToConstant(name.to_string()).into_err(var_pos))
}
}
}
// xxx[???]... = rhs, xxx.prop... = rhs
Expr::Index(x, _) | Expr::Dot(x, _) => {
Expr::Index(ref x, _) | Expr::Dot(ref x, _) => {
match check_lvalue(&x.rhs, matches!(lhs, Expr::Dot(_, _))) {
None => match &x.lhs {
None => match x.lhs {
// var[???] = rhs, var.??? = rhs
Expr::Variable(_, _, _) => {
Ok(Stmt::Assignment(Box::new((lhs, op_info, rhs)), op_pos))
}
// expr[???] = rhs, expr.??? = rhs
expr => {
ref expr => {
Err(PERR::AssignmentToInvalidLHS("".to_string()).into_err(expr.position()))
}
},
@ -2993,7 +2993,7 @@ fn parse_anon_fn(
#[cfg(not(feature = "unchecked"))]
settings.ensure_level_within_max_limit(state.max_expr_depth)?;
let mut params: StaticVec<_> = Default::default();
let mut params_list: StaticVec<_> = Default::default();
if input.next().expect(NEVER_ENDS).0 != Token::Or {
if !match_token(input, Token::Pipe).0 {
@ -3001,12 +3001,12 @@ fn parse_anon_fn(
match input.next().expect(NEVER_ENDS) {
(Token::Pipe, _) => break,
(Token::Identifier(s), pos) => {
if params.iter().any(|(p, _)| p == &s) {
if params_list.iter().any(|(p, _)| p == &s) {
return Err(PERR::FnDuplicatedParam("".to_string(), s).into_err(pos));
}
let s = state.get_identifier(s);
state.stack.push((s.clone(), AccessMode::ReadWrite));
params.push((s, pos))
params_list.push((s, pos))
}
(Token::LexError(err), pos) => return Err(err.into_err(pos)),
(_, pos) => {
@ -3040,29 +3040,26 @@ fn parse_anon_fn(
// External variables may need to be processed in a consistent order,
// so extract them into a list.
let externals: StaticVec<Identifier> = {
#[cfg(not(feature = "no_closure"))]
{
state
.external_vars
.iter()
.map(|(name, _)| name.clone())
.collect()
}
#[cfg(feature = "no_closure")]
Default::default()
};
#[cfg(not(feature = "no_closure"))]
let externals: StaticVec<Identifier> = state
.external_vars
.iter()
.map(|(name, _)| name.clone())
.collect();
let mut params: StaticVec<_> = if cfg!(not(feature = "no_closure")) {
externals
.iter()
.cloned()
.chain(params.into_iter().map(|(v, _)| v))
.collect()
} else {
params.into_iter().map(|(v, _)| v).collect()
};
params.shrink_to_fit();
let mut params = StaticVec::with_capacity(
params_list.len()
+ if cfg!(not(feature = "no_closure")) {
externals.len()
} else {
0
},
);
#[cfg(not(feature = "no_closure"))]
params.extend(externals.iter().cloned());
params.extend(params_list.into_iter().map(|(v, _)| v));
// Create unique function name by hashing the script body plus the parameters.
let hasher = &mut get_hasher();