Code style cleanup.
This commit is contained in:
parent
8ca24059b1
commit
743d48f44f
14
src/ast.rs
14
src/ast.rs
@ -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.
|
||||
|
473
src/dynamic.rs
473
src/dynamic.rs
@ -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()),
|
||||
}
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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"))]
|
||||
|
@ -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();
|
||||
|
Loading…
Reference in New Issue
Block a user