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.
|
/// Get the statements of this statements block.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn statements(&mut self) -> &mut StaticVec<Stmt> {
|
pub fn statements_mut(&mut self) -> &mut StaticVec<Stmt> {
|
||||||
&mut self.0
|
&mut self.0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1537,18 +1537,6 @@ impl FnCallHashes {
|
|||||||
pub fn is_native_only(&self) -> bool {
|
pub fn is_native_only(&self) -> bool {
|
||||||
self.script.is_none()
|
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.
|
/// _(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)]
|
#[inline(always)]
|
||||||
fn deref(&self) -> &Self::Target {
|
fn deref(&self) -> &Self::Target {
|
||||||
match &self.0 {
|
match self.0 {
|
||||||
DynamicReadLockInner::Reference(reference) => *reference,
|
DynamicReadLockInner::Reference(ref reference) => *reference,
|
||||||
#[cfg(not(feature = "no_closure"))]
|
#[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",
|
"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)]
|
#[inline(always)]
|
||||||
fn deref(&self) -> &Self::Target {
|
fn deref(&self) -> &Self::Target {
|
||||||
match &self.0 {
|
match self.0 {
|
||||||
DynamicWriteLockInner::Reference(reference) => *reference,
|
DynamicWriteLockInner::Reference(ref reference) => *reference,
|
||||||
#[cfg(not(feature = "no_closure"))]
|
#[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",
|
"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> {
|
impl<'d, T: Any + Clone> DerefMut for DynamicWriteLock<'d, T> {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||||
match &mut self.0 {
|
match self.0 {
|
||||||
DynamicWriteLockInner::Reference(reference) => *reference,
|
DynamicWriteLockInner::Reference(ref mut reference) => *reference,
|
||||||
#[cfg(not(feature = "no_closure"))]
|
#[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",
|
"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`].
|
/// Attach arbitrary data to this [`Dynamic`].
|
||||||
pub fn set_tag(&mut self, value: Tag) -> &mut Self {
|
pub fn set_tag(&mut self, value: Tag) -> &mut Self {
|
||||||
match &mut self.0 {
|
match self.0 {
|
||||||
Union::Unit(_, tag, _)
|
Union::Unit(_, ref mut tag, _)
|
||||||
| Union::Bool(_, tag, _)
|
| Union::Bool(_, ref mut tag, _)
|
||||||
| Union::Str(_, tag, _)
|
| Union::Str(_, ref mut tag, _)
|
||||||
| Union::Char(_, tag, _)
|
| Union::Char(_, ref mut tag, _)
|
||||||
| Union::Int(_, tag, _)
|
| Union::Int(_, ref mut tag, _)
|
||||||
| Union::FnPtr(_, tag, _)
|
| Union::FnPtr(_, ref mut tag, _)
|
||||||
| Union::Variant(_, tag, _) => *tag = value,
|
| Union::Variant(_, ref mut tag, _) => *tag = value,
|
||||||
|
|
||||||
#[cfg(not(feature = "no_float"))]
|
#[cfg(not(feature = "no_float"))]
|
||||||
Union::Float(_, tag, _) => *tag = value,
|
Union::Float(_, ref mut tag, _) => *tag = value,
|
||||||
#[cfg(feature = "decimal")]
|
#[cfg(feature = "decimal")]
|
||||||
Union::Decimal(_, tag, _) => *tag = value,
|
Union::Decimal(_, ref mut tag, _) => *tag = value,
|
||||||
#[cfg(not(feature = "no_index"))]
|
#[cfg(not(feature = "no_index"))]
|
||||||
Union::Array(_, tag, _) => *tag = value,
|
Union::Array(_, ref mut tag, _) => *tag = value,
|
||||||
#[cfg(not(feature = "no_object"))]
|
#[cfg(not(feature = "no_object"))]
|
||||||
Union::Map(_, tag, _) => *tag = value,
|
Union::Map(_, ref mut tag, _) => *tag = value,
|
||||||
#[cfg(not(feature = "no_std"))]
|
#[cfg(not(feature = "no_std"))]
|
||||||
Union::TimeStamp(_, tag, _) => *tag = value,
|
Union::TimeStamp(_, ref mut tag, _) => *tag = value,
|
||||||
#[cfg(not(feature = "no_closure"))]
|
#[cfg(not(feature = "no_closure"))]
|
||||||
Union::Shared(_, tag, _) => *tag = value,
|
Union::Shared(_, ref mut tag, _) => *tag = value,
|
||||||
}
|
}
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
@ -420,7 +420,7 @@ impl Dynamic {
|
|||||||
/// Otherwise, this call panics if the data is currently borrowed for write.
|
/// Otherwise, this call panics if the data is currently borrowed for write.
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn type_id(&self) -> TypeId {
|
pub fn type_id(&self) -> TypeId {
|
||||||
match &self.0 {
|
match self.0 {
|
||||||
Union::Unit(_, _, _) => TypeId::of::<()>(),
|
Union::Unit(_, _, _) => TypeId::of::<()>(),
|
||||||
Union::Bool(_, _, _) => TypeId::of::<bool>(),
|
Union::Bool(_, _, _) => TypeId::of::<bool>(),
|
||||||
Union::Str(_, _, _) => TypeId::of::<ImmutableString>(),
|
Union::Str(_, _, _) => TypeId::of::<ImmutableString>(),
|
||||||
@ -438,17 +438,15 @@ impl Dynamic {
|
|||||||
#[cfg(not(feature = "no_std"))]
|
#[cfg(not(feature = "no_std"))]
|
||||||
Union::TimeStamp(_, _, _) => TypeId::of::<Instant>(),
|
Union::TimeStamp(_, _, _) => TypeId::of::<Instant>(),
|
||||||
|
|
||||||
Union::Variant(value, _, _) => value.as_ref().as_ref().type_id(),
|
Union::Variant(ref value, _, _) => (***value).type_id(),
|
||||||
|
|
||||||
#[cfg(not(feature = "no_closure"))]
|
#[cfg(not(feature = "no_closure"))]
|
||||||
Union::Shared(cell, _, _) => {
|
#[cfg(not(feature = "sync"))]
|
||||||
#[cfg(not(feature = "sync"))]
|
Union::Shared(ref cell, _, _) => (*cell.borrow()).type_id(),
|
||||||
let value = cell.borrow();
|
|
||||||
#[cfg(feature = "sync")]
|
|
||||||
let value = cell.read().unwrap();
|
|
||||||
|
|
||||||
(*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`].
|
/// 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.
|
/// Otherwise, this call panics if the data is currently borrowed for write.
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn type_name(&self) -> &'static str {
|
pub fn type_name(&self) -> &'static str {
|
||||||
match &self.0 {
|
match self.0 {
|
||||||
Union::Unit(_, _, _) => "()",
|
Union::Unit(_, _, _) => "()",
|
||||||
Union::Bool(_, _, _) => "bool",
|
Union::Bool(_, _, _) => "bool",
|
||||||
Union::Str(_, _, _) => "string",
|
Union::Str(_, _, _) => "string",
|
||||||
@ -477,17 +475,17 @@ impl Dynamic {
|
|||||||
#[cfg(not(feature = "no_std"))]
|
#[cfg(not(feature = "no_std"))]
|
||||||
Union::TimeStamp(_, _, _) => "timestamp",
|
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 = "no_closure"))]
|
||||||
#[cfg(not(feature = "sync"))]
|
#[cfg(not(feature = "sync"))]
|
||||||
Union::Shared(cell, _, _) => cell
|
Union::Shared(ref cell, _, _) => cell
|
||||||
.try_borrow()
|
.try_borrow()
|
||||||
.map(|v| (*v).type_name())
|
.map(|v| (*v).type_name())
|
||||||
.unwrap_or("<shared>"),
|
.unwrap_or("<shared>"),
|
||||||
#[cfg(not(feature = "no_closure"))]
|
#[cfg(not(feature = "no_closure"))]
|
||||||
#[cfg(feature = "sync")]
|
#[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) {
|
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||||
std::mem::discriminant(&self.0).hash(state);
|
std::mem::discriminant(&self.0).hash(state);
|
||||||
|
|
||||||
match &self.0 {
|
match self.0 {
|
||||||
Union::Unit(_, _, _) => ().hash(state),
|
Union::Unit(_, _, _) => ().hash(state),
|
||||||
Union::Bool(b, _, _) => b.hash(state),
|
Union::Bool(ref b, _, _) => b.hash(state),
|
||||||
Union::Str(s, _, _) => s.hash(state),
|
Union::Str(ref s, _, _) => s.hash(state),
|
||||||
Union::Char(c, _, _) => c.hash(state),
|
Union::Char(ref c, _, _) => c.hash(state),
|
||||||
Union::Int(i, _, _) => i.hash(state),
|
Union::Int(ref i, _, _) => i.hash(state),
|
||||||
#[cfg(not(feature = "no_float"))]
|
#[cfg(not(feature = "no_float"))]
|
||||||
Union::Float(f, _, _) => f.hash(state),
|
Union::Float(ref f, _, _) => f.hash(state),
|
||||||
#[cfg(not(feature = "no_index"))]
|
#[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"))]
|
#[cfg(not(feature = "no_object"))]
|
||||||
Union::Map(m, _, _) => m.as_ref().hash(state),
|
Union::Map(ref m, _, _) => m.as_ref().hash(state),
|
||||||
Union::FnPtr(f, _, _) => f.hash(state),
|
Union::FnPtr(ref f, _, _) => f.hash(state),
|
||||||
|
|
||||||
#[cfg(not(feature = "no_closure"))]
|
#[cfg(not(feature = "no_closure"))]
|
||||||
Union::Shared(cell, _, _) => {
|
#[cfg(not(feature = "sync"))]
|
||||||
#[cfg(not(feature = "sync"))]
|
Union::Shared(ref cell, _, _) => (*cell.borrow()).hash(state),
|
||||||
let value = cell.borrow();
|
|
||||||
#[cfg(feature = "sync")]
|
|
||||||
let value = cell.read().unwrap();
|
|
||||||
|
|
||||||
(*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_i32"))]
|
||||||
#[cfg(not(feature = "only_i64"))]
|
#[cfg(not(feature = "only_i64"))]
|
||||||
Union::Variant(value, _, _) => {
|
Union::Variant(ref value, _, _) => {
|
||||||
let value = value.as_ref().as_ref();
|
let value_any = (***value).as_any();
|
||||||
let _type_id = value.type_id();
|
let type_id = value_any.type_id();
|
||||||
let _value_any = value.as_any();
|
|
||||||
|
|
||||||
if _type_id == TypeId::of::<u8>() {
|
if type_id == TypeId::of::<u8>() {
|
||||||
TypeId::of::<u8>().hash(state);
|
TypeId::of::<u8>().hash(state);
|
||||||
_value_any.downcast_ref::<u8>().expect(CHECKED).hash(state);
|
value_any.downcast_ref::<u8>().expect(CHECKED).hash(state);
|
||||||
} else if _type_id == TypeId::of::<u16>() {
|
} else if type_id == TypeId::of::<u16>() {
|
||||||
TypeId::of::<u16>().hash(state);
|
TypeId::of::<u16>().hash(state);
|
||||||
_value_any.downcast_ref::<u16>().expect(CHECKED).hash(state);
|
value_any.downcast_ref::<u16>().expect(CHECKED).hash(state);
|
||||||
} else if _type_id == TypeId::of::<u32>() {
|
} else if type_id == TypeId::of::<u32>() {
|
||||||
TypeId::of::<u32>().hash(state);
|
TypeId::of::<u32>().hash(state);
|
||||||
_value_any.downcast_ref::<u32>().expect(CHECKED).hash(state);
|
value_any.downcast_ref::<u32>().expect(CHECKED).hash(state);
|
||||||
} else if _type_id == TypeId::of::<u64>() {
|
} else if type_id == TypeId::of::<u64>() {
|
||||||
TypeId::of::<u64>().hash(state);
|
TypeId::of::<u64>().hash(state);
|
||||||
_value_any.downcast_ref::<u64>().expect(CHECKED).hash(state);
|
value_any.downcast_ref::<u64>().expect(CHECKED).hash(state);
|
||||||
} else if _type_id == TypeId::of::<i8>() {
|
} else if type_id == TypeId::of::<i8>() {
|
||||||
TypeId::of::<i8>().hash(state);
|
TypeId::of::<i8>().hash(state);
|
||||||
_value_any.downcast_ref::<i8>().expect(CHECKED).hash(state);
|
value_any.downcast_ref::<i8>().expect(CHECKED).hash(state);
|
||||||
} else if _type_id == TypeId::of::<i16>() {
|
} else if type_id == TypeId::of::<i16>() {
|
||||||
TypeId::of::<i16>().hash(state);
|
TypeId::of::<i16>().hash(state);
|
||||||
_value_any.downcast_ref::<i16>().expect(CHECKED).hash(state);
|
value_any.downcast_ref::<i16>().expect(CHECKED).hash(state);
|
||||||
} else if _type_id == TypeId::of::<i32>() {
|
} else if type_id == TypeId::of::<i32>() {
|
||||||
TypeId::of::<i32>().hash(state);
|
TypeId::of::<i32>().hash(state);
|
||||||
_value_any.downcast_ref::<i32>().expect(CHECKED).hash(state);
|
value_any.downcast_ref::<i32>().expect(CHECKED).hash(state);
|
||||||
} else if _type_id == TypeId::of::<i64>() {
|
} else if type_id == TypeId::of::<i64>() {
|
||||||
TypeId::of::<i64>().hash(state);
|
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")))]
|
#[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);
|
TypeId::of::<u128>().hash(state);
|
||||||
_value_any
|
value_any.downcast_ref::<u128>().expect(CHECKED).hash(state);
|
||||||
.downcast_ref::<u128>()
|
} else if type_id == TypeId::of::<i128>() {
|
||||||
.expect(CHECKED)
|
|
||||||
.hash(state);
|
|
||||||
} else if _type_id == TypeId::of::<i128>() {
|
|
||||||
TypeId::of::<i128>().hash(state);
|
TypeId::of::<i128>().hash(state);
|
||||||
_value_any
|
value_any.downcast_ref::<i128>().expect(CHECKED).hash(state);
|
||||||
.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 {
|
impl fmt::Display for Dynamic {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
match &self.0 {
|
match self.0 {
|
||||||
Union::Unit(_, _, _) => write!(f, ""),
|
Union::Unit(_, _, _) => write!(f, ""),
|
||||||
Union::Bool(value, _, _) => fmt::Display::fmt(value, f),
|
Union::Bool(ref value, _, _) => fmt::Display::fmt(value, f),
|
||||||
Union::Str(value, _, _) => fmt::Display::fmt(value, f),
|
Union::Str(ref value, _, _) => fmt::Display::fmt(value, f),
|
||||||
Union::Char(value, _, _) => fmt::Display::fmt(value, f),
|
Union::Char(ref value, _, _) => fmt::Display::fmt(value, f),
|
||||||
Union::Int(value, _, _) => fmt::Display::fmt(value, f),
|
Union::Int(ref value, _, _) => fmt::Display::fmt(value, f),
|
||||||
#[cfg(not(feature = "no_float"))]
|
#[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")]
|
#[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"))]
|
#[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"))]
|
#[cfg(not(feature = "no_object"))]
|
||||||
Union::Map(value, _, _) => {
|
Union::Map(ref value, _, _) => {
|
||||||
f.write_str("#")?;
|
f.write_str("#")?;
|
||||||
fmt::Debug::fmt(value, f)
|
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"))]
|
#[cfg(not(feature = "no_std"))]
|
||||||
Union::TimeStamp(_, _, _) => f.write_str("<timestamp>"),
|
Union::TimeStamp(_, _, _) => f.write_str("<timestamp>"),
|
||||||
|
|
||||||
Union::Variant(value, _, _) => {
|
Union::Variant(ref value, _, _) => {
|
||||||
let value = value.as_ref().as_ref();
|
let _value_any = (***value).as_any();
|
||||||
let _type_id = value.type_id();
|
let _type_id = _value_any.type_id();
|
||||||
let _value_any = value.as_any();
|
|
||||||
|
|
||||||
#[cfg(not(feature = "only_i32"))]
|
#[cfg(not(feature = "only_i32"))]
|
||||||
#[cfg(not(feature = "only_i64"))]
|
#[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);
|
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 = "no_closure"))]
|
||||||
#[cfg(not(feature = "sync"))]
|
#[cfg(not(feature = "sync"))]
|
||||||
Union::Shared(cell, _, _) => {
|
Union::Shared(ref cell, _, _) => {
|
||||||
if let Ok(v) = cell.try_borrow() {
|
if let Ok(v) = cell.try_borrow() {
|
||||||
fmt::Display::fmt(&*v, f)
|
fmt::Display::fmt(&*v, f)
|
||||||
} else {
|
} else {
|
||||||
@ -691,38 +679,37 @@ impl fmt::Display for Dynamic {
|
|||||||
}
|
}
|
||||||
#[cfg(not(feature = "no_closure"))]
|
#[cfg(not(feature = "no_closure"))]
|
||||||
#[cfg(feature = "sync")]
|
#[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 {
|
impl fmt::Debug for Dynamic {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
match &self.0 {
|
match self.0 {
|
||||||
Union::Unit(value, _, _) => fmt::Debug::fmt(value, f),
|
Union::Unit(ref value, _, _) => fmt::Debug::fmt(value, f),
|
||||||
Union::Bool(value, _, _) => fmt::Debug::fmt(value, f),
|
Union::Bool(ref value, _, _) => fmt::Debug::fmt(value, f),
|
||||||
Union::Str(value, _, _) => fmt::Debug::fmt(value, f),
|
Union::Str(ref value, _, _) => fmt::Debug::fmt(value, f),
|
||||||
Union::Char(value, _, _) => fmt::Debug::fmt(value, f),
|
Union::Char(ref value, _, _) => fmt::Debug::fmt(value, f),
|
||||||
Union::Int(value, _, _) => fmt::Debug::fmt(value, f),
|
Union::Int(ref value, _, _) => fmt::Debug::fmt(value, f),
|
||||||
#[cfg(not(feature = "no_float"))]
|
#[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")]
|
#[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"))]
|
#[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"))]
|
#[cfg(not(feature = "no_object"))]
|
||||||
Union::Map(value, _, _) => {
|
Union::Map(ref value, _, _) => {
|
||||||
f.write_str("#")?;
|
f.write_str("#")?;
|
||||||
fmt::Debug::fmt(value, f)
|
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"))]
|
#[cfg(not(feature = "no_std"))]
|
||||||
Union::TimeStamp(_, _, _) => write!(f, "<timestamp>"),
|
Union::TimeStamp(_, _, _) => write!(f, "<timestamp>"),
|
||||||
|
|
||||||
Union::Variant(value, _, _) => {
|
Union::Variant(ref value, _, _) => {
|
||||||
let value = value.as_ref().as_ref();
|
let _value_any = (***value).as_any();
|
||||||
let _type_id = value.type_id();
|
let _type_id = _value_any.type_id();
|
||||||
let _value_any = value.as_any();
|
|
||||||
|
|
||||||
const CHECKED: &str = "never fails because the type was checked";
|
const CHECKED: &str = "never fails because the type was checked";
|
||||||
|
|
||||||
@ -760,12 +747,12 @@ impl fmt::Debug for Dynamic {
|
|||||||
return fmt::Debug::fmt(_value_any.downcast_ref::<i128>().expect(CHECKED), f);
|
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 = "no_closure"))]
|
||||||
#[cfg(not(feature = "sync"))]
|
#[cfg(not(feature = "sync"))]
|
||||||
Union::Shared(cell, _, _) => {
|
Union::Shared(ref cell, _, _) => {
|
||||||
if let Ok(v) = cell.try_borrow() {
|
if let Ok(v) = cell.try_borrow() {
|
||||||
write!(f, "{:?} (shared)", *v)
|
write!(f, "{:?} (shared)", *v)
|
||||||
} else {
|
} else {
|
||||||
@ -774,7 +761,7 @@ impl fmt::Debug for Dynamic {
|
|||||||
}
|
}
|
||||||
#[cfg(not(feature = "no_closure"))]
|
#[cfg(not(feature = "no_closure"))]
|
||||||
#[cfg(feature = "sync")]
|
#[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`].
|
/// Set the [`AccessMode`] for this [`Dynamic`].
|
||||||
pub(crate) fn set_access_mode(&mut self, typ: AccessMode) -> &mut Self {
|
pub(crate) fn set_access_mode(&mut self, typ: AccessMode) -> &mut Self {
|
||||||
match &mut self.0 {
|
match self.0 {
|
||||||
Union::Unit(_, _, access)
|
Union::Unit(_, _, ref mut access)
|
||||||
| Union::Bool(_, _, access)
|
| Union::Bool(_, _, ref mut access)
|
||||||
| Union::Str(_, _, access)
|
| Union::Str(_, _, ref mut access)
|
||||||
| Union::Char(_, _, access)
|
| Union::Char(_, _, ref mut access)
|
||||||
| Union::Int(_, _, access)
|
| Union::Int(_, _, ref mut access)
|
||||||
| Union::FnPtr(_, _, access)
|
| Union::FnPtr(_, _, ref mut access)
|
||||||
| Union::Variant(_, _, access) => *access = typ,
|
| Union::Variant(_, _, ref mut access) => *access = typ,
|
||||||
|
|
||||||
#[cfg(not(feature = "no_float"))]
|
#[cfg(not(feature = "no_float"))]
|
||||||
Union::Float(_, _, access) => *access = typ,
|
Union::Float(_, _, ref mut access) => *access = typ,
|
||||||
#[cfg(feature = "decimal")]
|
#[cfg(feature = "decimal")]
|
||||||
Union::Decimal(_, _, access) => *access = typ,
|
Union::Decimal(_, _, ref mut access) => *access = typ,
|
||||||
#[cfg(not(feature = "no_index"))]
|
#[cfg(not(feature = "no_index"))]
|
||||||
Union::Array(a, _, access) => {
|
Union::Array(ref mut a, _, ref mut access) => {
|
||||||
*access = typ;
|
*access = typ;
|
||||||
a.iter_mut().for_each(|v| {
|
a.iter_mut().for_each(|v| {
|
||||||
v.set_access_mode(typ);
|
v.set_access_mode(typ);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
#[cfg(not(feature = "no_object"))]
|
#[cfg(not(feature = "no_object"))]
|
||||||
Union::Map(m, _, access) => {
|
Union::Map(ref mut m, _, ref mut access) => {
|
||||||
*access = typ;
|
*access = typ;
|
||||||
m.values_mut().for_each(|v| {
|
m.values_mut().for_each(|v| {
|
||||||
v.set_access_mode(typ);
|
v.set_access_mode(typ);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
#[cfg(not(feature = "no_std"))]
|
#[cfg(not(feature = "no_std"))]
|
||||||
Union::TimeStamp(_, _, access) => *access = typ,
|
Union::TimeStamp(_, _, ref mut access) => *access = typ,
|
||||||
#[cfg(not(feature = "no_closure"))]
|
#[cfg(not(feature = "no_closure"))]
|
||||||
Union::Shared(_, _, access) => *access = typ,
|
Union::Shared(_, _, ref mut access) => *access = typ,
|
||||||
}
|
}
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
@ -967,17 +954,22 @@ impl Dynamic {
|
|||||||
#[cfg(not(feature = "no_closure"))]
|
#[cfg(not(feature = "no_closure"))]
|
||||||
match self.0 {
|
match self.0 {
|
||||||
Union::Shared(_, _, ReadOnly) => return true,
|
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,
|
ReadWrite => false,
|
||||||
ReadOnly => true,
|
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?
|
/// Can this [`Dynamic`] be hashed?
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub(crate) fn is_hashable(&self) -> bool {
|
pub(crate) fn is_hashable(&self) -> bool {
|
||||||
match &self.0 {
|
match self.0 {
|
||||||
Union::Unit(_, _, _)
|
Union::Unit(_, _, _)
|
||||||
| Union::Bool(_, _, _)
|
| Union::Bool(_, _, _)
|
||||||
| Union::Str(_, _, _)
|
| Union::Str(_, _, _)
|
||||||
@ -1004,14 +996,12 @@ impl Dynamic {
|
|||||||
Union::Map(_, _, _) => true,
|
Union::Map(_, _, _) => true,
|
||||||
|
|
||||||
#[cfg(not(feature = "no_closure"))]
|
#[cfg(not(feature = "no_closure"))]
|
||||||
Union::Shared(cell, _, _) => {
|
#[cfg(not(feature = "sync"))]
|
||||||
#[cfg(not(feature = "sync"))]
|
Union::Shared(ref cell, _, _) => cell.borrow().is_hashable(),
|
||||||
let value = cell.borrow();
|
|
||||||
#[cfg(feature = "sync")]
|
|
||||||
let value = cell.read().unwrap();
|
|
||||||
|
|
||||||
value.is_hashable()
|
#[cfg(not(feature = "no_closure"))]
|
||||||
}
|
#[cfg(feature = "sync")]
|
||||||
|
Union::Shared(ref cell, _, _) => cell.read().unwrap().is_hashable(),
|
||||||
|
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
@ -1388,20 +1378,15 @@ impl Dynamic {
|
|||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn flatten_clone(&self) -> Self {
|
pub fn flatten_clone(&self) -> Self {
|
||||||
#[cfg(not(feature = "no_closure"))]
|
match self.0 {
|
||||||
match &self.0 {
|
#[cfg(not(feature = "no_closure"))]
|
||||||
Union::Shared(cell, _, _) => {
|
#[cfg(not(feature = "sync"))]
|
||||||
#[cfg(not(feature = "sync"))]
|
Union::Shared(ref cell, _, _) => cell.borrow().clone(),
|
||||||
let value = cell.borrow();
|
#[cfg(not(feature = "no_closure"))]
|
||||||
#[cfg(feature = "sync")]
|
#[cfg(feature = "sync")]
|
||||||
let value = cell.read().unwrap();
|
Union::Shared(ref cell, _, _) => cell.read().unwrap().clone(),
|
||||||
|
_ => self.clone(),
|
||||||
return value.clone();
|
|
||||||
}
|
|
||||||
_ => (),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
self.clone()
|
|
||||||
}
|
}
|
||||||
/// Flatten the [`Dynamic`].
|
/// Flatten the [`Dynamic`].
|
||||||
///
|
///
|
||||||
@ -1412,30 +1397,20 @@ impl Dynamic {
|
|||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn flatten(self) -> Self {
|
pub fn flatten(self) -> Self {
|
||||||
#[cfg(not(feature = "no_closure"))]
|
|
||||||
match self.0 {
|
match self.0 {
|
||||||
Union::Shared(cell, _, _) => {
|
#[cfg(not(feature = "no_closure"))]
|
||||||
return crate::fn_native::shared_try_take(cell).map_or_else(
|
Union::Shared(cell, _, _) => crate::fn_native::shared_try_take(cell).map_or_else(
|
||||||
|cell| {
|
#[cfg(not(feature = "sync"))]
|
||||||
#[cfg(not(feature = "sync"))]
|
|cell| cell.borrow().clone(),
|
||||||
let value = cell.borrow();
|
#[cfg(feature = "sync")]
|
||||||
#[cfg(feature = "sync")]
|
|cell| cell.read().unwrap().clone(),
|
||||||
let value = cell.read().unwrap();
|
#[cfg(not(feature = "sync"))]
|
||||||
|
|value| value.into_inner(),
|
||||||
value.clone()
|
#[cfg(feature = "sync")]
|
||||||
},
|
|value| value.into_inner().unwrap(),
|
||||||
|value| {
|
),
|
||||||
#[cfg(not(feature = "sync"))]
|
_ => self,
|
||||||
return value.into_inner();
|
|
||||||
#[cfg(feature = "sync")]
|
|
||||||
return value.into_inner().unwrap();
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
|
||||||
_ => (),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
self
|
|
||||||
}
|
}
|
||||||
/// Flatten the [`Dynamic`] in place.
|
/// Flatten the [`Dynamic`] in place.
|
||||||
///
|
///
|
||||||
@ -1445,26 +1420,20 @@ impl Dynamic {
|
|||||||
/// outstanding references, or a cloned copy otherwise.
|
/// outstanding references, or a cloned copy otherwise.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub(crate) fn flatten_in_place(&mut self) -> &mut Self {
|
pub(crate) fn flatten_in_place(&mut self) -> &mut Self {
|
||||||
#[cfg(not(feature = "no_closure"))]
|
|
||||||
match self.0 {
|
match self.0 {
|
||||||
|
#[cfg(not(feature = "no_closure"))]
|
||||||
Union::Shared(_, _, _) => match std::mem::take(self).0 {
|
Union::Shared(_, _, _) => match std::mem::take(self).0 {
|
||||||
Union::Shared(cell, _, _) => {
|
Union::Shared(cell, _, _) => {
|
||||||
*self = crate::fn_native::shared_try_take(cell).map_or_else(
|
*self = crate::fn_native::shared_try_take(cell).map_or_else(
|
||||||
|cell| {
|
#[cfg(not(feature = "sync"))]
|
||||||
#[cfg(not(feature = "sync"))]
|
|cell| cell.borrow().clone(),
|
||||||
let value = cell.borrow();
|
#[cfg(feature = "sync")]
|
||||||
#[cfg(feature = "sync")]
|
|cell| cell.read().unwrap().clone(),
|
||||||
let value = cell.read().unwrap();
|
#[cfg(not(feature = "sync"))]
|
||||||
|
|value| value.into_inner(),
|
||||||
value.clone()
|
#[cfg(feature = "sync")]
|
||||||
},
|
|value| value.into_inner().unwrap(),
|
||||||
|value| {
|
);
|
||||||
#[cfg(not(feature = "sync"))]
|
|
||||||
return value.into_inner();
|
|
||||||
#[cfg(feature = "sync")]
|
|
||||||
return value.into_inner().unwrap();
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
},
|
},
|
||||||
@ -1577,73 +1546,73 @@ impl Dynamic {
|
|||||||
// Coded this way in order to maximally leverage potentials for dead-code removal.
|
// Coded this way in order to maximally leverage potentials for dead-code removal.
|
||||||
|
|
||||||
if TypeId::of::<T>() == TypeId::of::<INT>() {
|
if TypeId::of::<T>() == TypeId::of::<INT>() {
|
||||||
return match &self.0 {
|
return match self.0 {
|
||||||
Union::Int(value, _, _) => value.as_any().downcast_ref::<T>(),
|
Union::Int(ref value, _, _) => value.as_any().downcast_ref::<T>(),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
#[cfg(not(feature = "no_float"))]
|
#[cfg(not(feature = "no_float"))]
|
||||||
if TypeId::of::<T>() == TypeId::of::<FLOAT>() {
|
if TypeId::of::<T>() == TypeId::of::<FLOAT>() {
|
||||||
return match &self.0 {
|
return match self.0 {
|
||||||
Union::Float(value, _, _) => value.as_ref().as_any().downcast_ref::<T>(),
|
Union::Float(ref value, _, _) => value.as_ref().as_any().downcast_ref::<T>(),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
#[cfg(feature = "decimal")]
|
#[cfg(feature = "decimal")]
|
||||||
if TypeId::of::<T>() == TypeId::of::<Decimal>() {
|
if TypeId::of::<T>() == TypeId::of::<Decimal>() {
|
||||||
return match &self.0 {
|
return match self.0 {
|
||||||
Union::Decimal(value, _, _) => value.as_ref().as_any().downcast_ref::<T>(),
|
Union::Decimal(ref value, _, _) => value.as_ref().as_any().downcast_ref::<T>(),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
if TypeId::of::<T>() == TypeId::of::<bool>() {
|
if TypeId::of::<T>() == TypeId::of::<bool>() {
|
||||||
return match &self.0 {
|
return match self.0 {
|
||||||
Union::Bool(value, _, _) => value.as_any().downcast_ref::<T>(),
|
Union::Bool(ref value, _, _) => value.as_any().downcast_ref::<T>(),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
if TypeId::of::<T>() == TypeId::of::<ImmutableString>() {
|
if TypeId::of::<T>() == TypeId::of::<ImmutableString>() {
|
||||||
return match &self.0 {
|
return match self.0 {
|
||||||
Union::Str(value, _, _) => value.as_any().downcast_ref::<T>(),
|
Union::Str(ref value, _, _) => value.as_any().downcast_ref::<T>(),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
if TypeId::of::<T>() == TypeId::of::<char>() {
|
if TypeId::of::<T>() == TypeId::of::<char>() {
|
||||||
return match &self.0 {
|
return match self.0 {
|
||||||
Union::Char(value, _, _) => value.as_any().downcast_ref::<T>(),
|
Union::Char(ref value, _, _) => value.as_any().downcast_ref::<T>(),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
#[cfg(not(feature = "no_index"))]
|
#[cfg(not(feature = "no_index"))]
|
||||||
if TypeId::of::<T>() == TypeId::of::<Array>() {
|
if TypeId::of::<T>() == TypeId::of::<Array>() {
|
||||||
return match &self.0 {
|
return match self.0 {
|
||||||
Union::Array(value, _, _) => value.as_ref().as_any().downcast_ref::<T>(),
|
Union::Array(ref value, _, _) => value.as_ref().as_any().downcast_ref::<T>(),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
#[cfg(not(feature = "no_object"))]
|
#[cfg(not(feature = "no_object"))]
|
||||||
if TypeId::of::<T>() == TypeId::of::<Map>() {
|
if TypeId::of::<T>() == TypeId::of::<Map>() {
|
||||||
return match &self.0 {
|
return match self.0 {
|
||||||
Union::Map(value, _, _) => value.as_ref().as_any().downcast_ref::<T>(),
|
Union::Map(ref value, _, _) => value.as_ref().as_any().downcast_ref::<T>(),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
if TypeId::of::<T>() == TypeId::of::<FnPtr>() {
|
if TypeId::of::<T>() == TypeId::of::<FnPtr>() {
|
||||||
return match &self.0 {
|
return match self.0 {
|
||||||
Union::FnPtr(value, _, _) => value.as_ref().as_any().downcast_ref::<T>(),
|
Union::FnPtr(ref value, _, _) => value.as_ref().as_any().downcast_ref::<T>(),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
#[cfg(not(feature = "no_std"))]
|
#[cfg(not(feature = "no_std"))]
|
||||||
if TypeId::of::<T>() == TypeId::of::<Instant>() {
|
if TypeId::of::<T>() == TypeId::of::<Instant>() {
|
||||||
return match &self.0 {
|
return match self.0 {
|
||||||
Union::TimeStamp(value, _, _) => value.as_ref().as_any().downcast_ref::<T>(),
|
Union::TimeStamp(ref value, _, _) => value.as_ref().as_any().downcast_ref::<T>(),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
if TypeId::of::<T>() == TypeId::of::<()>() {
|
if TypeId::of::<T>() == TypeId::of::<()>() {
|
||||||
return match &self.0 {
|
return match self.0 {
|
||||||
Union::Unit(value, _, _) => value.as_any().downcast_ref::<T>(),
|
Union::Unit(ref value, _, _) => value.as_any().downcast_ref::<T>(),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -1651,8 +1620,8 @@ impl Dynamic {
|
|||||||
return self.as_any().downcast_ref::<T>();
|
return self.as_any().downcast_ref::<T>();
|
||||||
}
|
}
|
||||||
|
|
||||||
match &self.0 {
|
match self.0 {
|
||||||
Union::Variant(value, _, _) => value.as_ref().as_ref().as_any().downcast_ref::<T>(),
|
Union::Variant(ref value, _, _) => (***value).as_any().downcast_ref::<T>(),
|
||||||
#[cfg(not(feature = "no_closure"))]
|
#[cfg(not(feature = "no_closure"))]
|
||||||
Union::Shared(_, _, _) => None,
|
Union::Shared(_, _, _) => None,
|
||||||
_ => None,
|
_ => None,
|
||||||
@ -1668,73 +1637,83 @@ impl Dynamic {
|
|||||||
// Coded this way in order to maximally leverage potentials for dead-code removal.
|
// Coded this way in order to maximally leverage potentials for dead-code removal.
|
||||||
|
|
||||||
if TypeId::of::<T>() == TypeId::of::<INT>() {
|
if TypeId::of::<T>() == TypeId::of::<INT>() {
|
||||||
return match &mut self.0 {
|
return match self.0 {
|
||||||
Union::Int(value, _, _) => value.as_mut_any().downcast_mut::<T>(),
|
Union::Int(ref mut value, _, _) => value.as_mut_any().downcast_mut::<T>(),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
#[cfg(not(feature = "no_float"))]
|
#[cfg(not(feature = "no_float"))]
|
||||||
if TypeId::of::<T>() == TypeId::of::<FLOAT>() {
|
if TypeId::of::<T>() == TypeId::of::<FLOAT>() {
|
||||||
return match &mut self.0 {
|
return match self.0 {
|
||||||
Union::Float(value, _, _) => value.as_mut().as_mut_any().downcast_mut::<T>(),
|
Union::Float(ref mut value, _, _) => {
|
||||||
|
value.as_mut().as_mut_any().downcast_mut::<T>()
|
||||||
|
}
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
#[cfg(feature = "decimal")]
|
#[cfg(feature = "decimal")]
|
||||||
if TypeId::of::<T>() == TypeId::of::<Decimal>() {
|
if TypeId::of::<T>() == TypeId::of::<Decimal>() {
|
||||||
return match &mut self.0 {
|
return match self.0 {
|
||||||
Union::Decimal(value, _, _) => value.as_mut().as_mut_any().downcast_mut::<T>(),
|
Union::Decimal(ref mut value, _, _) => {
|
||||||
|
value.as_mut().as_mut_any().downcast_mut::<T>()
|
||||||
|
}
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
if TypeId::of::<T>() == TypeId::of::<bool>() {
|
if TypeId::of::<T>() == TypeId::of::<bool>() {
|
||||||
return match &mut self.0 {
|
return match self.0 {
|
||||||
Union::Bool(value, _, _) => value.as_mut_any().downcast_mut::<T>(),
|
Union::Bool(ref mut value, _, _) => value.as_mut_any().downcast_mut::<T>(),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
if TypeId::of::<T>() == TypeId::of::<ImmutableString>() {
|
if TypeId::of::<T>() == TypeId::of::<ImmutableString>() {
|
||||||
return match &mut self.0 {
|
return match self.0 {
|
||||||
Union::Str(value, _, _) => value.as_mut_any().downcast_mut::<T>(),
|
Union::Str(ref mut value, _, _) => value.as_mut_any().downcast_mut::<T>(),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
if TypeId::of::<T>() == TypeId::of::<char>() {
|
if TypeId::of::<T>() == TypeId::of::<char>() {
|
||||||
return match &mut self.0 {
|
return match self.0 {
|
||||||
Union::Char(value, _, _) => value.as_mut_any().downcast_mut::<T>(),
|
Union::Char(ref mut value, _, _) => value.as_mut_any().downcast_mut::<T>(),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
#[cfg(not(feature = "no_index"))]
|
#[cfg(not(feature = "no_index"))]
|
||||||
if TypeId::of::<T>() == TypeId::of::<Array>() {
|
if TypeId::of::<T>() == TypeId::of::<Array>() {
|
||||||
return match &mut self.0 {
|
return match self.0 {
|
||||||
Union::Array(value, _, _) => value.as_mut().as_mut_any().downcast_mut::<T>(),
|
Union::Array(ref mut value, _, _) => {
|
||||||
|
value.as_mut().as_mut_any().downcast_mut::<T>()
|
||||||
|
}
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
#[cfg(not(feature = "no_object"))]
|
#[cfg(not(feature = "no_object"))]
|
||||||
if TypeId::of::<T>() == TypeId::of::<Map>() {
|
if TypeId::of::<T>() == TypeId::of::<Map>() {
|
||||||
return match &mut self.0 {
|
return match self.0 {
|
||||||
Union::Map(value, _, _) => value.as_mut().as_mut_any().downcast_mut::<T>(),
|
Union::Map(ref mut value, _, _) => value.as_mut().as_mut_any().downcast_mut::<T>(),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
if TypeId::of::<T>() == TypeId::of::<FnPtr>() {
|
if TypeId::of::<T>() == TypeId::of::<FnPtr>() {
|
||||||
return match &mut self.0 {
|
return match self.0 {
|
||||||
Union::FnPtr(value, _, _) => value.as_mut().as_mut_any().downcast_mut::<T>(),
|
Union::FnPtr(ref mut value, _, _) => {
|
||||||
|
value.as_mut().as_mut_any().downcast_mut::<T>()
|
||||||
|
}
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
#[cfg(not(feature = "no_std"))]
|
#[cfg(not(feature = "no_std"))]
|
||||||
if TypeId::of::<T>() == TypeId::of::<Instant>() {
|
if TypeId::of::<T>() == TypeId::of::<Instant>() {
|
||||||
return match &mut self.0 {
|
return match self.0 {
|
||||||
Union::TimeStamp(value, _, _) => value.as_mut().as_mut_any().downcast_mut::<T>(),
|
Union::TimeStamp(ref mut value, _, _) => {
|
||||||
|
value.as_mut().as_mut_any().downcast_mut::<T>()
|
||||||
|
}
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
if TypeId::of::<T>() == TypeId::of::<()>() {
|
if TypeId::of::<T>() == TypeId::of::<()>() {
|
||||||
return match &mut self.0 {
|
return match self.0 {
|
||||||
Union::Unit(value, _, _) => value.as_mut_any().downcast_mut::<T>(),
|
Union::Unit(ref mut value, _, _) => value.as_mut_any().downcast_mut::<T>(),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -1742,8 +1721,8 @@ impl Dynamic {
|
|||||||
return self.as_mut_any().downcast_mut::<T>();
|
return self.as_mut_any().downcast_mut::<T>();
|
||||||
}
|
}
|
||||||
|
|
||||||
match &mut self.0 {
|
match self.0 {
|
||||||
Union::Variant(value, _, _) => value.as_mut().as_mut_any().downcast_mut::<T>(),
|
Union::Variant(ref mut value, _, _) => (***value).as_mut_any().downcast_mut::<T>(),
|
||||||
#[cfg(not(feature = "no_closure"))]
|
#[cfg(not(feature = "no_closure"))]
|
||||||
Union::Shared(_, _, _) => None,
|
Union::Shared(_, _, _) => None,
|
||||||
_ => None,
|
_ => None,
|
||||||
@ -1898,8 +1877,8 @@ impl Dynamic {
|
|||||||
#[cfg(feature = "sync")]
|
#[cfg(feature = "sync")]
|
||||||
let value = cell.read().unwrap();
|
let value = cell.read().unwrap();
|
||||||
|
|
||||||
match &value.0 {
|
match value.0 {
|
||||||
Union::Str(s, _, _) => Ok(s.clone()),
|
Union::Str(ref s, _, _) => Ok(s.clone()),
|
||||||
_ => Err((*value).type_name()),
|
_ => Err((*value).type_name()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1320,9 +1320,9 @@ impl Engine {
|
|||||||
// xxx.fn_name(arg_expr_list)
|
// xxx.fn_name(arg_expr_list)
|
||||||
Expr::FnCall(x, pos) if !x.is_qualified() && new_val.is_none() => {
|
Expr::FnCall(x, pos) if !x.is_qualified() && new_val.is_none() => {
|
||||||
let FnCallExpr { name, hashes, .. } = x.as_ref();
|
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(
|
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(...) = ???
|
// xxx.fn_name(...) = ???
|
||||||
@ -1340,11 +1340,11 @@ impl Engine {
|
|||||||
new_val.expect("never fails because `new_val` is `Some`");
|
new_val.expect("never fails because `new_val` is `Some`");
|
||||||
let index = name.into();
|
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,
|
mods, state, lib, target, index, *pos, true, false, level,
|
||||||
)?;
|
)?;
|
||||||
self.eval_op_assignment(
|
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))?;
|
.map_err(|err| err.fill_position(new_pos))?;
|
||||||
}
|
}
|
||||||
@ -1369,11 +1369,11 @@ impl Engine {
|
|||||||
|
|
||||||
if op_info.is_some() {
|
if op_info.is_some() {
|
||||||
let hash = FnCallHashes::from_native(*hash_get);
|
let hash = FnCallHashes::from_native(*hash_get);
|
||||||
let mut args = [target.as_mut()];
|
let args = &mut [target.as_mut()];
|
||||||
let (mut orig_val, _) = self
|
let (mut orig_val, _) = self
|
||||||
.exec_fn_call(
|
.exec_fn_call(
|
||||||
mods, state, lib, getter, hash, &mut args, is_ref, true, *pos,
|
mods, state, lib, getter, hash, args, is_ref, true, *pos, None,
|
||||||
None, level,
|
level,
|
||||||
)
|
)
|
||||||
.or_else(|err| match *err {
|
.or_else(|err| match *err {
|
||||||
// Try an indexer if property does not exist
|
// Try an indexer if property does not exist
|
||||||
@ -1413,16 +1413,14 @@ impl Engine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let hash = FnCallHashes::from_native(*hash_set);
|
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(
|
self.exec_fn_call(
|
||||||
mods, state, lib, setter, hash, &mut args, is_ref, true, *pos, None,
|
mods, state, lib, setter, hash, args, is_ref, true, *pos, None, level,
|
||||||
level,
|
|
||||||
)
|
)
|
||||||
.or_else(|err| match *err {
|
.or_else(|err| match *err {
|
||||||
// Try an indexer if property does not exist
|
// Try an indexer if property does not exist
|
||||||
EvalAltResult::ErrorDotExpr(_, _) => {
|
EvalAltResult::ErrorDotExpr(_, _) => {
|
||||||
let mut prop = name.into();
|
let args = &mut [target, &mut name.into(), &mut new_val];
|
||||||
let args = &mut [target, &mut prop, &mut new_val];
|
|
||||||
let hash_set =
|
let hash_set =
|
||||||
FnCallHashes::from_native(crate::calc_fn_hash(FN_IDX_SET, 3));
|
FnCallHashes::from_native(crate::calc_fn_hash(FN_IDX_SET, 3));
|
||||||
self.exec_fn_call(
|
self.exec_fn_call(
|
||||||
@ -1443,10 +1441,9 @@ impl Engine {
|
|||||||
Expr::Property(x) => {
|
Expr::Property(x) => {
|
||||||
let ((getter, hash_get), _, (name, pos)) = x.as_ref();
|
let ((getter, hash_get), _, (name, pos)) = x.as_ref();
|
||||||
let hash = FnCallHashes::from_native(*hash_get);
|
let hash = FnCallHashes::from_native(*hash_get);
|
||||||
let mut args = [target.as_mut()];
|
let args = &mut [target.as_mut()];
|
||||||
self.exec_fn_call(
|
self.exec_fn_call(
|
||||||
mods, state, lib, getter, hash, &mut args, is_ref, true, *pos, None,
|
mods, state, lib, getter, hash, args, is_ref, true, *pos, None, level,
|
||||||
level,
|
|
||||||
)
|
)
|
||||||
.map_or_else(
|
.map_or_else(
|
||||||
|err| match *err {
|
|err| match *err {
|
||||||
@ -1471,8 +1468,8 @@ impl Engine {
|
|||||||
}
|
}
|
||||||
// {xxx:map}.sub_lhs[expr] | {xxx:map}.sub_lhs.expr
|
// {xxx:map}.sub_lhs[expr] | {xxx:map}.sub_lhs.expr
|
||||||
Expr::Index(x, x_pos) | Expr::Dot(x, x_pos) if target.is::<Map>() => {
|
Expr::Index(x, x_pos) | Expr::Dot(x, x_pos) if target.is::<Map>() => {
|
||||||
let mut val = match &x.lhs {
|
let val_target = &mut match x.lhs {
|
||||||
Expr::Property(p) => {
|
Expr::Property(ref p) => {
|
||||||
let (name, pos) = &p.2;
|
let (name, pos) = &p.2;
|
||||||
let index = name.into();
|
let index = name.into();
|
||||||
self.get_indexed_mut(
|
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
|
// {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 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(
|
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()
|
val.into()
|
||||||
}
|
}
|
||||||
@ -1493,21 +1490,21 @@ impl Engine {
|
|||||||
"function call in dot chain should not be namespace-qualified"
|
"function call in dot chain should not be namespace-qualified"
|
||||||
),
|
),
|
||||||
// Others - syntax error
|
// Others - syntax error
|
||||||
expr => unreachable!("invalid dot expression: {:?}", expr),
|
ref expr => unreachable!("invalid dot expression: {:?}", expr),
|
||||||
};
|
};
|
||||||
let rhs_chain = match_chain_type(rhs);
|
let rhs_chain = match_chain_type(rhs);
|
||||||
|
|
||||||
self.eval_dot_index_chain_helper(
|
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,
|
rhs_chain, level, new_val,
|
||||||
)
|
)
|
||||||
.map_err(|err| err.fill_position(*x_pos))
|
.map_err(|err| err.fill_position(*x_pos))
|
||||||
}
|
}
|
||||||
// xxx.sub_lhs[expr] | xxx.sub_lhs.expr
|
// xxx.sub_lhs[expr] | xxx.sub_lhs.expr
|
||||||
Expr::Index(x, x_pos) | Expr::Dot(x, x_pos) => {
|
Expr::Index(x, x_pos) | Expr::Dot(x, x_pos) => {
|
||||||
match &x.lhs {
|
match x.lhs {
|
||||||
// xxx.prop[expr] | xxx.prop.expr
|
// xxx.prop[expr] | xxx.prop.expr
|
||||||
Expr::Property(p) => {
|
Expr::Property(ref p) => {
|
||||||
let ((getter, hash_get), (setter, hash_set), (name, pos)) =
|
let ((getter, hash_get), (setter, hash_set), (name, pos)) =
|
||||||
p.as_ref();
|
p.as_ref();
|
||||||
let rhs_chain = match_chain_type(rhs);
|
let rhs_chain = match_chain_type(rhs);
|
||||||
@ -1570,8 +1567,8 @@ impl Engine {
|
|||||||
|err| match *err {
|
|err| match *err {
|
||||||
// Try an indexer if property does not exist
|
// Try an indexer if property does not exist
|
||||||
EvalAltResult::ErrorDotExpr(_, _) => {
|
EvalAltResult::ErrorDotExpr(_, _) => {
|
||||||
let mut prop = name.into();
|
let args =
|
||||||
let args = &mut [target.as_mut(), &mut prop, val];
|
&mut [target.as_mut(), &mut name.into(), val];
|
||||||
let hash_set = FnCallHashes::from_native(
|
let hash_set = FnCallHashes::from_native(
|
||||||
crate::calc_fn_hash(FN_IDX_SET, 3),
|
crate::calc_fn_hash(FN_IDX_SET, 3),
|
||||||
);
|
);
|
||||||
@ -1598,12 +1595,12 @@ impl Engine {
|
|||||||
Ok((result, may_be_changed))
|
Ok((result, may_be_changed))
|
||||||
}
|
}
|
||||||
// xxx.fn_name(arg_expr_list)[expr] | xxx.fn_name(arg_expr_list).expr
|
// 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 FnCallExpr { name, hashes, .. } = f.as_ref();
|
||||||
let rhs_chain = match_chain_type(rhs);
|
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(
|
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 val = &mut val;
|
||||||
let target = &mut val.into();
|
let target = &mut val.into();
|
||||||
@ -1612,14 +1609,14 @@ impl Engine {
|
|||||||
mods, state, lib, this_ptr, target, root, &x.rhs, idx_values,
|
mods, state, lib, this_ptr, target, root, &x.rhs, idx_values,
|
||||||
rhs_chain, level, new_val,
|
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
|
// xxx.module::fn_name(...) - syntax error
|
||||||
Expr::FnCall(_, _) => unreachable!(
|
Expr::FnCall(_, _) => unreachable!(
|
||||||
"function call in dot chain should not be namespace-qualified"
|
"function call in dot chain should not be namespace-qualified"
|
||||||
),
|
),
|
||||||
// Others - syntax error
|
// Others - syntax error
|
||||||
expr => unreachable!("invalid dot expression: {:?}", expr),
|
ref expr => unreachable!("invalid dot expression: {:?}", expr),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Syntax error
|
// Syntax error
|
||||||
@ -2109,7 +2106,7 @@ impl Engine {
|
|||||||
let namespace = namespace
|
let namespace = namespace
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.expect("never fails because function call is qualified");
|
.expect("never fails because function call is qualified");
|
||||||
let hash = hashes.native_hash();
|
let hash = hashes.native;
|
||||||
self.make_qualified_function_call(
|
self.make_qualified_function_call(
|
||||||
scope, mods, state, lib, this_ptr, namespace, name, args, constants, hash,
|
scope, mods, state, lib, this_ptr, namespace, name, args, constants, hash,
|
||||||
*pos, level,
|
*pos, level,
|
||||||
@ -2702,7 +2699,7 @@ impl Engine {
|
|||||||
let namespace = namespace
|
let namespace = namespace
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.expect("never fails because function call is qualified");
|
.expect("never fails because function call is qualified");
|
||||||
let hash = hashes.native_hash();
|
let hash = hashes.native;
|
||||||
self.make_qualified_function_call(
|
self.make_qualified_function_call(
|
||||||
scope, mods, state, lib, this_ptr, namespace, name, args, constants, hash,
|
scope, mods, state, lib, this_ptr, namespace, name, args, constants, hash,
|
||||||
*pos, level,
|
*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
|
// One of the operands is a custom type, so it is never built-in
|
||||||
if x.is_variant() || y.is_variant() {
|
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
|
// Disallow comparisons between different numeric types
|
||||||
return None;
|
None
|
||||||
}
|
} else if type1 != type2 {
|
||||||
|
// If the types are not the same, default to not compare
|
||||||
// If the types are not the same, default to not compare
|
match op {
|
||||||
if type1 != type2 {
|
|
||||||
return match op {
|
|
||||||
"!=" => Some(|_, _| Ok(Dynamic::TRUE)),
|
"!=" => Some(|_, _| Ok(Dynamic::TRUE)),
|
||||||
"==" | ">" | ">=" | "<" | "<=" => Some(|_, _| Ok(Dynamic::FALSE)),
|
"==" | ">" | ">=" | "<" | "<=" => Some(|_, _| Ok(Dynamic::FALSE)),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
}
|
||||||
}
|
} else {
|
||||||
|
// Disallow comparisons between the same type
|
||||||
// Disallow comparisons between the same type
|
None
|
||||||
return None;
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
let types_pair = (type1, type2);
|
let types_pair = (type1, type2);
|
||||||
|
|
||||||
macro_rules! impl_op {
|
macro_rules! impl_op {
|
||||||
($xx:ident $op:tt $yy:ident) => {
|
($xx:ident $op:tt $yy:ident) => {
|
||||||
return Some(|_, args| {
|
Some(|_, args| {
|
||||||
let x = &*args[0].read_lock::<$xx>().expect(BUILTIN);
|
let x = &*args[0].read_lock::<$xx>().expect(BUILTIN);
|
||||||
let y = &*args[1].read_lock::<$yy>().expect(BUILTIN);
|
let y = &*args[1].read_lock::<$yy>().expect(BUILTIN);
|
||||||
Ok((x $op y).into())
|
Ok((x $op y).into())
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
($xx:ident . $func:ident ( $yy:ty )) => {
|
($xx:ident . $func:ident ( $yy:ty )) => {
|
||||||
return Some(|_, args| {
|
Some(|_, args| {
|
||||||
let x = &*args[0].read_lock::<$xx>().expect(BUILTIN);
|
let x = &*args[0].read_lock::<$xx>().expect(BUILTIN);
|
||||||
let y = &*args[1].read_lock::<$yy>().expect(BUILTIN);
|
let y = &*args[1].read_lock::<$yy>().expect(BUILTIN);
|
||||||
Ok(x.$func(y).into())
|
Ok(x.$func(y).into())
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
($xx:ident . $func:ident ( $yy:ident . $yyy:ident () )) => {
|
($xx:ident . $func:ident ( $yy:ident . $yyy:ident () )) => {
|
||||||
return Some(|_, args| {
|
Some(|_, args| {
|
||||||
let x = &*args[0].read_lock::<$xx>().expect(BUILTIN);
|
let x = &*args[0].read_lock::<$xx>().expect(BUILTIN);
|
||||||
let y = &*args[1].read_lock::<$yy>().expect(BUILTIN);
|
let y = &*args[1].read_lock::<$yy>().expect(BUILTIN);
|
||||||
Ok(x.$func(y.$yyy()).into())
|
Ok(x.$func(y.$yyy()).into())
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
($func:ident ( $op:tt )) => {
|
($func:ident ( $op:tt )) => {
|
||||||
return Some(|_, args| {
|
Some(|_, args| {
|
||||||
let (x, y) = $func(args);
|
let (x, y) = $func(args);
|
||||||
Ok((x $op y).into())
|
Ok((x $op y).into())
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
($base:ty => $xx:ident $op:tt $yy:ident) => {
|
($base:ty => $xx:ident $op:tt $yy:ident) => {
|
||||||
return Some(|_, args| {
|
Some(|_, args| {
|
||||||
let x = args[0].$xx().expect(BUILTIN) as $base;
|
let x = args[0].$xx().expect(BUILTIN) as $base;
|
||||||
let y = args[1].$yy().expect(BUILTIN) as $base;
|
let y = args[1].$yy().expect(BUILTIN) as $base;
|
||||||
Ok((x $op y).into())
|
Ok((x $op y).into())
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
($base:ty => $xx:ident . $func:ident ( $yy:ident as $yyy:ty)) => {
|
($base:ty => $xx:ident . $func:ident ( $yy:ident as $yyy:ty)) => {
|
||||||
return Some(|_, args| {
|
Some(|_, args| {
|
||||||
let x = args[0].$xx().expect(BUILTIN) as $base;
|
let x = args[0].$xx().expect(BUILTIN) as $base;
|
||||||
let y = args[1].$yy().expect(BUILTIN) as $base;
|
let y = args[1].$yy().expect(BUILTIN) as $base;
|
||||||
Ok(x.$func(y as $yyy).into())
|
Ok(x.$func(y as $yyy).into())
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
($base:ty => $func:ident ( $xx:ident, $yy:ident )) => {
|
($base:ty => $func:ident ( $xx:ident, $yy:ident )) => {
|
||||||
return Some(|_, args| {
|
Some(|_, args| {
|
||||||
let x = args[0].$xx().expect(BUILTIN) as $base;
|
let x = args[0].$xx().expect(BUILTIN) as $base;
|
||||||
let y = args[1].$yy().expect(BUILTIN) as $base;
|
let y = args[1].$yy().expect(BUILTIN) as $base;
|
||||||
$func(x, y).map(Into::<Dynamic>::into)
|
$func(x, y).map(Into::<Dynamic>::into)
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
(from $base:ty => $xx:ident $op:tt $yy:ident) => {
|
(from $base:ty => $xx:ident $op:tt $yy:ident) => {
|
||||||
return Some(|_, args| {
|
Some(|_, args| {
|
||||||
let x = <$base>::from(args[0].$xx().expect(BUILTIN));
|
let x = <$base>::from(args[0].$xx().expect(BUILTIN));
|
||||||
let y = <$base>::from(args[1].$yy().expect(BUILTIN));
|
let y = <$base>::from(args[1].$yy().expect(BUILTIN));
|
||||||
Ok((x $op y).into())
|
Ok((x $op y).into())
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
(from $base:ty => $xx:ident . $func:ident ( $yy:ident )) => {
|
(from $base:ty => $xx:ident . $func:ident ( $yy:ident )) => {
|
||||||
return Some(|_, args| {
|
Some(|_, args| {
|
||||||
let x = <$base>::from(args[0].$xx().expect(BUILTIN));
|
let x = <$base>::from(args[0].$xx().expect(BUILTIN));
|
||||||
let y = <$base>::from(args[1].$yy().expect(BUILTIN));
|
let y = <$base>::from(args[1].$yy().expect(BUILTIN));
|
||||||
Ok(x.$func(y).into())
|
Ok(x.$func(y).into())
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
(from $base:ty => $func:ident ( $xx:ident, $yy:ident )) => {
|
(from $base:ty => $func:ident ( $xx:ident, $yy:ident )) => {
|
||||||
return Some(|_, args| {
|
Some(|_, args| {
|
||||||
let x = <$base>::from(args[0].$xx().expect(BUILTIN));
|
let x = <$base>::from(args[0].$xx().expect(BUILTIN));
|
||||||
let y = <$base>::from(args[1].$yy().expect(BUILTIN));
|
let y = <$base>::from(args[1].$yy().expect(BUILTIN));
|
||||||
$func(x, y).map(Into::<Dynamic>::into)
|
$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) => {
|
($x:ty, $xx:ident, $y:ty, $yy:ident) => {
|
||||||
#[cfg(not(feature = "no_float"))]
|
#[cfg(not(feature = "no_float"))]
|
||||||
if types_pair == (TypeId::of::<$x>(), TypeId::of::<$y>()) {
|
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),
|
"-" => 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),
|
"<" => 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) => {
|
($x:ty, $xx:ident, $y:ty, $yy:ident) => {
|
||||||
#[cfg(feature = "decimal")]
|
#[cfg(feature = "decimal")]
|
||||||
if types_pair == (TypeId::of::<$x>(), TypeId::of::<$y>()) {
|
if types_pair == (TypeId::of::<$x>(), TypeId::of::<$y>()) {
|
||||||
if cfg!(not(feature = "unBUILTIN")) {
|
#[cfg(not(feature = "unchecked"))]
|
||||||
use crate::packages::arithmetic::decimal_functions::*;
|
use crate::packages::arithmetic::decimal_functions::*;
|
||||||
|
|
||||||
match op {
|
#[cfg(not(feature = "unchecked"))]
|
||||||
"+" => impl_op!(from Decimal => add($xx, $yy)),
|
match op {
|
||||||
"-" => impl_op!(from Decimal => subtract($xx, $yy)),
|
"+" => return impl_op!(from Decimal => add($xx, $yy)),
|
||||||
"*" => impl_op!(from Decimal => multiply($xx, $yy)),
|
"-" => return impl_op!(from Decimal => subtract($xx, $yy)),
|
||||||
"/" => impl_op!(from Decimal => divide($xx, $yy)),
|
"*" => return impl_op!(from Decimal => multiply($xx, $yy)),
|
||||||
"%" => impl_op!(from Decimal => modulo($xx, $yy)),
|
"/" => return impl_op!(from Decimal => divide($xx, $yy)),
|
||||||
"**" => impl_op!(from Decimal => power($xx, $yy)),
|
"%" => return impl_op!(from Decimal => modulo($xx, $yy)),
|
||||||
_ => ()
|
"**" => return 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(feature = "unchecked")]
|
||||||
|
use rust_decimal::MathematicalOps;
|
||||||
|
|
||||||
|
#[cfg(feature = "unchecked")]
|
||||||
match op {
|
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),
|
||||||
">=" => 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)
|
(s1, s2)
|
||||||
}
|
}
|
||||||
|
|
||||||
match op {
|
return match op {
|
||||||
"+" => {
|
"+" => Some(|_, args| {
|
||||||
return Some(|_, args| {
|
let x = args[0].as_char().expect(BUILTIN);
|
||||||
let x = args[0].as_char().expect(BUILTIN);
|
let y = &*args[1].read_lock::<ImmutableString>().expect(BUILTIN);
|
||||||
let y = &*args[1].read_lock::<ImmutableString>().expect(BUILTIN);
|
Ok(format!("{}{}", x, y).into())
|
||||||
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(>)),
|
||||||
">=" => 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
|
// string op char
|
||||||
if types_pair == (TypeId::of::<ImmutableString>(), TypeId::of::<char>()) {
|
if types_pair == (TypeId::of::<ImmutableString>(), TypeId::of::<char>()) {
|
||||||
@ -263,36 +261,30 @@ pub fn get_builtin_binary_op_fn(
|
|||||||
(s1, s2)
|
(s1, s2)
|
||||||
}
|
}
|
||||||
|
|
||||||
match op {
|
return match op {
|
||||||
"+" => {
|
"+" => Some(|_, args| {
|
||||||
return Some(|_, args| {
|
let x = &*args[0].read_lock::<ImmutableString>().expect(BUILTIN);
|
||||||
let x = &*args[0].read_lock::<ImmutableString>().expect(BUILTIN);
|
let y = args[1].as_char().expect(BUILTIN);
|
||||||
let y = args[1].as_char().expect(BUILTIN);
|
Ok((x + y).into())
|
||||||
Ok((x + y).into())
|
}),
|
||||||
})
|
"-" => Some(|_, args| {
|
||||||
}
|
let x = &*args[0].read_lock::<ImmutableString>().expect(BUILTIN);
|
||||||
"-" => {
|
let y = args[1].as_char().expect(BUILTIN);
|
||||||
return Some(|_, args| {
|
Ok((x - y).into())
|
||||||
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(>)),
|
||||||
">=" => 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 => {
|
OP_CONTAINS => Some(|_, args| {
|
||||||
return Some(|_, args| {
|
let s = &*args[0].read_lock::<ImmutableString>().expect(BUILTIN);
|
||||||
let s = &*args[0].read_lock::<ImmutableString>().expect(BUILTIN);
|
let c = args[1].as_char().expect(BUILTIN);
|
||||||
let c = args[1].as_char().expect(BUILTIN);
|
Ok((s.contains(c)).into())
|
||||||
Ok((s.contains(c)).into())
|
}),
|
||||||
})
|
_ => None,
|
||||||
}
|
};
|
||||||
_ => return None,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// map op string
|
// map op string
|
||||||
@ -300,10 +292,10 @@ pub fn get_builtin_binary_op_fn(
|
|||||||
if types_pair == (TypeId::of::<crate::Map>(), TypeId::of::<ImmutableString>()) {
|
if types_pair == (TypeId::of::<crate::Map>(), TypeId::of::<ImmutableString>()) {
|
||||||
use crate::Map;
|
use crate::Map;
|
||||||
|
|
||||||
match op {
|
return match op {
|
||||||
OP_CONTAINS => impl_op!(Map.contains_key(ImmutableString.as_str())),
|
OP_CONTAINS => impl_op!(Map.contains_key(ImmutableString.as_str())),
|
||||||
_ => return None,
|
_ => None,
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Default comparison operators for different types
|
// Default comparison operators for different types
|
||||||
@ -318,35 +310,36 @@ pub fn get_builtin_binary_op_fn(
|
|||||||
// Beyond here, type1 == type2
|
// Beyond here, type1 == type2
|
||||||
|
|
||||||
if type1 == TypeId::of::<INT>() {
|
if type1 == TypeId::of::<INT>() {
|
||||||
if cfg!(not(feature = "unBUILTIN")) {
|
#[cfg(not(feature = "unchecked"))]
|
||||||
use crate::packages::arithmetic::arith_basic::INT::functions::*;
|
use crate::packages::arithmetic::arith_basic::INT::functions::*;
|
||||||
|
|
||||||
match op {
|
#[cfg(not(feature = "unchecked"))]
|
||||||
"+" => impl_op!(INT => add(as_int, as_int)),
|
match op {
|
||||||
"-" => impl_op!(INT => subtract(as_int, as_int)),
|
"+" => return impl_op!(INT => add(as_int, as_int)),
|
||||||
"*" => impl_op!(INT => multiply(as_int, as_int)),
|
"-" => return impl_op!(INT => subtract(as_int, as_int)),
|
||||||
"/" => impl_op!(INT => divide(as_int, as_int)),
|
"*" => return impl_op!(INT => multiply(as_int, as_int)),
|
||||||
"%" => impl_op!(INT => modulo(as_int, as_int)),
|
"/" => return impl_op!(INT => divide(as_int, as_int)),
|
||||||
"**" => impl_op!(INT => power(as_int, as_int)),
|
"%" => return impl_op!(INT => modulo(as_int, as_int)),
|
||||||
">>" => impl_op!(INT => shift_right(as_int, as_int)),
|
"**" => return impl_op!(INT => power(as_int, as_int)),
|
||||||
"<<" => impl_op!(INT => shift_left(as_int, as_int)),
|
">>" => return impl_op!(INT => shift_right(as_int, as_int)),
|
||||||
_ => (),
|
"<<" => return 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(feature = "unchecked")]
|
||||||
match op {
|
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),
|
"!=" => 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),
|
"|" => 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>() {
|
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),
|
"!=" => 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),
|
"|" => 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>() {
|
if type1 == TypeId::of::<ImmutableString>() {
|
||||||
match op {
|
return match op {
|
||||||
"+" => impl_op!(ImmutableString + ImmutableString),
|
"+" => impl_op!(ImmutableString + ImmutableString),
|
||||||
"-" => impl_op!(ImmutableString - ImmutableString),
|
"-" => 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),
|
"<" => impl_op!(ImmutableString < ImmutableString),
|
||||||
"<=" => impl_op!(ImmutableString <= ImmutableString),
|
"<=" => impl_op!(ImmutableString <= ImmutableString),
|
||||||
OP_CONTAINS => {
|
OP_CONTAINS => Some(|_, args| {
|
||||||
return Some(|_, args| {
|
let s1 = &*args[0].read_lock::<ImmutableString>().expect(BUILTIN);
|
||||||
let s1 = &*args[0].read_lock::<ImmutableString>().expect(BUILTIN);
|
let s2 = &*args[1].read_lock::<ImmutableString>().expect(BUILTIN);
|
||||||
let s2 = &*args[1].read_lock::<ImmutableString>().expect(BUILTIN);
|
Ok((s1.contains(s2.as_str())).into())
|
||||||
Ok((s1.contains(s2.as_str())).into())
|
}),
|
||||||
})
|
_ => None,
|
||||||
}
|
};
|
||||||
_ => return None,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if type1 == TypeId::of::<char>() {
|
if type1 == TypeId::of::<char>() {
|
||||||
match op {
|
return match op {
|
||||||
"+" => {
|
"+" => Some(|_, args| {
|
||||||
return Some(|_, args| {
|
let x = args[0].as_char().expect(BUILTIN);
|
||||||
let x = args[0].as_char().expect(BUILTIN);
|
let y = args[1].as_char().expect(BUILTIN);
|
||||||
let y = args[1].as_char().expect(BUILTIN);
|
Ok(format!("{}{}", x, y).into())
|
||||||
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),
|
||||||
">=" => 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::<()>() {
|
if type1 == TypeId::of::<()>() {
|
||||||
match op {
|
return match op {
|
||||||
"==" => return Some(|_, _| Ok(Dynamic::TRUE)),
|
"==" => Some(|_, _| Ok(Dynamic::TRUE)),
|
||||||
"!=" | ">" | ">=" | "<" | "<=" => return Some(|_, _| Ok(Dynamic::FALSE)),
|
"!=" | ">" | ">=" | "<" | "<=" => Some(|_, _| Ok(Dynamic::FALSE)),
|
||||||
_ => return None,
|
_ => None,
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
None
|
None
|
||||||
@ -444,53 +433,53 @@ pub fn get_builtin_op_assignment_fn(
|
|||||||
|
|
||||||
macro_rules! impl_op {
|
macro_rules! impl_op {
|
||||||
($x:ty = x $op:tt $yy:ident) => {
|
($x:ty = x $op:tt $yy:ident) => {
|
||||||
return Some(|_, args| {
|
Some(|_, args| {
|
||||||
let x = args[0].$yy().expect(BUILTIN);
|
let x = args[0].$yy().expect(BUILTIN);
|
||||||
let y = args[1].$yy().expect(BUILTIN) as $x;
|
let y = args[1].$yy().expect(BUILTIN) as $x;
|
||||||
Ok((*args[0].write_lock::<$x>().expect(BUILTIN) = x $op y).into())
|
Ok((*args[0].write_lock::<$x>().expect(BUILTIN) = x $op y).into())
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
($x:ident $op:tt $yy:ident) => {
|
($x:ident $op:tt $yy:ident) => {
|
||||||
return Some(|_, args| {
|
Some(|_, args| {
|
||||||
let y = args[1].$yy().expect(BUILTIN) as $x;
|
let y = args[1].$yy().expect(BUILTIN) as $x;
|
||||||
Ok((*args[0].write_lock::<$x>().expect(BUILTIN) $op y).into())
|
Ok((*args[0].write_lock::<$x>().expect(BUILTIN) $op y).into())
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
($x:ident $op:tt $yy:ident as $yyy:ty) => {
|
($x:ident $op:tt $yy:ident as $yyy:ty) => {
|
||||||
return Some(|_, args| {
|
Some(|_, args| {
|
||||||
let y = args[1].$yy().expect(BUILTIN) as $yyy;
|
let y = args[1].$yy().expect(BUILTIN) as $yyy;
|
||||||
Ok((*args[0].write_lock::<$x>().expect(BUILTIN) $op y).into())
|
Ok((*args[0].write_lock::<$x>().expect(BUILTIN) $op y).into())
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
($x:ty => $xx:ident . $func:ident ( $yy:ident as $yyy:ty )) => {
|
($x:ty => $xx:ident . $func:ident ( $yy:ident as $yyy:ty )) => {
|
||||||
return Some(|_, args| {
|
Some(|_, args| {
|
||||||
let x = args[0].$xx().expect(BUILTIN);
|
let x = args[0].$xx().expect(BUILTIN);
|
||||||
let y = args[1].$yy().expect(BUILTIN) as $x;
|
let y = args[1].$yy().expect(BUILTIN) as $x;
|
||||||
Ok((*args[0].write_lock::<$x>().expect(BUILTIN) = x.$func(y as $yyy)).into())
|
Ok((*args[0].write_lock::<$x>().expect(BUILTIN) = x.$func(y as $yyy)).into())
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
($x:ty => $func:ident ( $xx:ident, $yy:ident )) => {
|
($x:ty => $func:ident ( $xx:ident, $yy:ident )) => {
|
||||||
return Some(|_, args| {
|
Some(|_, args| {
|
||||||
let x = args[0].$xx().expect(BUILTIN);
|
let x = args[0].$xx().expect(BUILTIN);
|
||||||
let y = args[1].$yy().expect(BUILTIN) as $x;
|
let y = args[1].$yy().expect(BUILTIN) as $x;
|
||||||
Ok((*args[0].write_lock().expect(BUILTIN) = $func(x, y)?).into())
|
Ok((*args[0].write_lock().expect(BUILTIN) = $func(x, y)?).into())
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
(from $x:ident $op:tt $yy:ident) => {
|
(from $x:ident $op:tt $yy:ident) => {
|
||||||
return Some(|_, args| {
|
Some(|_, args| {
|
||||||
let y = <$x>::from(args[1].$yy().expect(BUILTIN));
|
let y = <$x>::from(args[1].$yy().expect(BUILTIN));
|
||||||
Ok((*args[0].write_lock::<$x>().expect(BUILTIN) $op y).into())
|
Ok((*args[0].write_lock::<$x>().expect(BUILTIN) $op y).into())
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
(from $x:ty => $xx:ident . $func:ident ( $yy:ident )) => {
|
(from $x:ty => $xx:ident . $func:ident ( $yy:ident )) => {
|
||||||
return Some(|_, args| {
|
Some(|_, args| {
|
||||||
let x = args[0].$xx().expect(BUILTIN);
|
let x = args[0].$xx().expect(BUILTIN);
|
||||||
let y = <$x>::from(args[1].$yy().expect(BUILTIN));
|
let y = <$x>::from(args[1].$yy().expect(BUILTIN));
|
||||||
Ok((*args[0].write_lock::<$x>().expect(BUILTIN) = x.$func(y)).into())
|
Ok((*args[0].write_lock::<$x>().expect(BUILTIN) = x.$func(y)).into())
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
(from $x:ty => $func:ident ( $xx:ident, $yy:ident )) => {
|
(from $x:ty => $func:ident ( $xx:ident, $yy:ident )) => {
|
||||||
return Some(|_, args| {
|
Some(|_, args| {
|
||||||
let x = args[0].$xx().expect(BUILTIN);
|
let x = args[0].$xx().expect(BUILTIN);
|
||||||
let y = <$x>::from(args[1].$yy().expect(BUILTIN));
|
let y = <$x>::from(args[1].$yy().expect(BUILTIN));
|
||||||
Ok((*args[0].write_lock().expect(BUILTIN) = $func(x, y)?).into())
|
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) => {
|
($x:ident, $xx:ident, $y:ty, $yy:ident) => {
|
||||||
#[cfg(not(feature = "no_float"))]
|
#[cfg(not(feature = "no_float"))]
|
||||||
if types_pair == (TypeId::of::<$x>(), TypeId::of::<$y>()) {
|
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 *= $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)),
|
"**=" => 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) => {
|
($x:ident, $xx:ident, $y:ty, $yy:ident) => {
|
||||||
#[cfg(feature = "decimal")]
|
#[cfg(feature = "decimal")]
|
||||||
if types_pair == (TypeId::of::<$x>(), TypeId::of::<$y>()) {
|
if types_pair == (TypeId::of::<$x>(), TypeId::of::<$y>()) {
|
||||||
if cfg!(not(feature = "unBUILTIN")) {
|
#[cfg(not(feature = "unchecked"))]
|
||||||
use crate::packages::arithmetic::decimal_functions::*;
|
use crate::packages::arithmetic::decimal_functions::*;
|
||||||
|
|
||||||
match op {
|
#[cfg(not(feature = "unchecked"))]
|
||||||
"+=" => impl_op!(from $x => add($xx, $yy)),
|
return match op {
|
||||||
"-=" => impl_op!(from $x => subtract($xx, $yy)),
|
"+=" => impl_op!(from $x => add($xx, $yy)),
|
||||||
"*=" => impl_op!(from $x => multiply($xx, $yy)),
|
"-=" => impl_op!(from $x => subtract($xx, $yy)),
|
||||||
"/=" => impl_op!(from $x => divide($xx, $yy)),
|
"*=" => impl_op!(from $x => multiply($xx, $yy)),
|
||||||
"%=" => impl_op!(from $x => modulo($xx, $yy)),
|
"/=" => impl_op!(from $x => divide($xx, $yy)),
|
||||||
"**=" => impl_op!(from $x => power($xx, $yy)),
|
"%=" => impl_op!(from $x => modulo($xx, $yy)),
|
||||||
_ => return None,
|
"**=" => impl_op!(from $x => power($xx, $yy)),
|
||||||
}
|
_ => None,
|
||||||
} else {
|
};
|
||||||
use rust_decimal::MathematicalOps;
|
|
||||||
|
|
||||||
match op {
|
#[cfg(feature = "unchecked")]
|
||||||
"+=" => impl_op!(from $x += $yy),
|
use rust_decimal::MathematicalOps;
|
||||||
"-=" => impl_op!(from $x -= $yy),
|
|
||||||
"*=" => impl_op!(from $x *= $yy),
|
#[cfg(feature = "unchecked")]
|
||||||
"/=" => impl_op!(from $x /= $yy),
|
return match op {
|
||||||
"%=" => impl_op!(from $x %= $yy),
|
"+=" => impl_op!(from $x += $yy),
|
||||||
"**=" => impl_op!(from $x => $xx.powd($yy)),
|
"-=" => impl_op!(from $x -= $yy),
|
||||||
_ => return None,
|
"*=" => 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
|
// string op= char
|
||||||
if types_pair == (TypeId::of::<ImmutableString>(), TypeId::of::<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),
|
||||||
"-=" => impl_op!(ImmutableString -= as_char as char),
|
"-=" => impl_op!(ImmutableString -= as_char as char),
|
||||||
_ => return None,
|
_ => None,
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
// char op= string
|
// char op= string
|
||||||
if types_pair == (TypeId::of::<char>(), TypeId::of::<ImmutableString>()) {
|
if types_pair == (TypeId::of::<char>(), TypeId::of::<ImmutableString>()) {
|
||||||
match op {
|
return match op {
|
||||||
"+=" => {
|
"+=" => Some(|_, args| {
|
||||||
return Some(|_, args| {
|
let mut ch = args[0].as_char().expect(BUILTIN).to_string();
|
||||||
let mut ch = args[0].as_char().expect(BUILTIN).to_string();
|
ch.push_str(
|
||||||
ch.push_str(
|
args[1]
|
||||||
args[1]
|
.read_lock::<ImmutableString>()
|
||||||
.read_lock::<ImmutableString>()
|
.expect(BUILTIN)
|
||||||
.expect(BUILTIN)
|
.as_str(),
|
||||||
.as_str(),
|
);
|
||||||
);
|
|
||||||
|
|
||||||
let mut x = args[0].write_lock::<Dynamic>().expect(BUILTIN);
|
let mut x = args[0].write_lock::<Dynamic>().expect(BUILTIN);
|
||||||
Ok((*x = ch.into()).into())
|
Ok((*x = ch.into()).into())
|
||||||
})
|
}),
|
||||||
}
|
_ => None,
|
||||||
_ => return None,
|
};
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// No built-in op-assignments for different types.
|
// No built-in op-assignments for different types.
|
||||||
@ -590,83 +579,78 @@ pub fn get_builtin_op_assignment_fn(
|
|||||||
|
|
||||||
// Beyond here, type1 == type2
|
// Beyond here, type1 == type2
|
||||||
if type1 == TypeId::of::<INT>() {
|
if type1 == TypeId::of::<INT>() {
|
||||||
if cfg!(not(feature = "unBUILTIN")) {
|
#[cfg(not(feature = "unchecked"))]
|
||||||
use crate::packages::arithmetic::arith_basic::INT::functions::*;
|
use crate::packages::arithmetic::arith_basic::INT::functions::*;
|
||||||
|
|
||||||
match op {
|
#[cfg(not(feature = "unchecked"))]
|
||||||
"+=" => impl_op!(INT => add(as_int, as_int)),
|
match op {
|
||||||
"-=" => impl_op!(INT => subtract(as_int, as_int)),
|
"+=" => return impl_op!(INT => add(as_int, as_int)),
|
||||||
"*=" => impl_op!(INT => multiply(as_int, as_int)),
|
"-=" => return impl_op!(INT => subtract(as_int, as_int)),
|
||||||
"/=" => impl_op!(INT => divide(as_int, as_int)),
|
"*=" => return impl_op!(INT => multiply(as_int, as_int)),
|
||||||
"%=" => impl_op!(INT => modulo(as_int, as_int)),
|
"/=" => return impl_op!(INT => divide(as_int, as_int)),
|
||||||
"**=" => impl_op!(INT => power(as_int, as_int)),
|
"%=" => return impl_op!(INT => modulo(as_int, as_int)),
|
||||||
">>=" => impl_op!(INT => shift_right(as_int, as_int)),
|
"**=" => return impl_op!(INT => power(as_int, as_int)),
|
||||||
"<<=" => impl_op!(INT => shift_left(as_int, as_int)),
|
">>=" => return impl_op!(INT => shift_right(as_int, as_int)),
|
||||||
_ => (),
|
"<<=" => return 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(feature = "unchecked")]
|
||||||
match op {
|
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),
|
"|=" => impl_op!(INT |= as_int),
|
||||||
"^=" => impl_op!(INT ^= as_int),
|
"^=" => impl_op!(INT ^= as_int),
|
||||||
_ => (),
|
_ => None,
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if type1 == TypeId::of::<bool>() {
|
if type1 == TypeId::of::<bool>() {
|
||||||
match op {
|
return match op {
|
||||||
"&=" => impl_op!(bool = x && as_bool),
|
"&=" => impl_op!(bool = x && as_bool),
|
||||||
"|=" => impl_op!(bool = x || as_bool),
|
"|=" => impl_op!(bool = x || as_bool),
|
||||||
_ => return None,
|
_ => None,
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if type1 == TypeId::of::<char>() {
|
if type1 == TypeId::of::<char>() {
|
||||||
match op {
|
return match op {
|
||||||
"+=" => {
|
"+=" => Some(|_, args| {
|
||||||
return Some(|_, args| {
|
let y = args[1].as_char().expect(BUILTIN);
|
||||||
let y = args[1].as_char().expect(BUILTIN);
|
let mut x = args[0].write_lock::<Dynamic>().expect(BUILTIN);
|
||||||
let mut x = args[0].write_lock::<Dynamic>().expect(BUILTIN);
|
Ok((*x = format!("{}{}", *x, y).into()).into())
|
||||||
Ok((*x = format!("{}{}", *x, y).into()).into())
|
}),
|
||||||
})
|
_ => None,
|
||||||
}
|
};
|
||||||
_ => return None,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if type1 == TypeId::of::<ImmutableString>() {
|
if type1 == TypeId::of::<ImmutableString>() {
|
||||||
match op {
|
return match op {
|
||||||
"+=" => {
|
"+=" => Some(|_, args| {
|
||||||
return Some(|_, args| {
|
let (first, second) = args.split_first_mut().expect(BUILTIN);
|
||||||
let (first, second) = args.split_first_mut().expect(BUILTIN);
|
let mut x = first.write_lock::<ImmutableString>().expect(BUILTIN);
|
||||||
let mut x = first.write_lock::<ImmutableString>().expect(BUILTIN);
|
let y = &*second[0].read_lock::<ImmutableString>().expect(BUILTIN);
|
||||||
let y = &*second[0].read_lock::<ImmutableString>().expect(BUILTIN);
|
Ok((*x += y).into())
|
||||||
Ok((*x += y).into())
|
}),
|
||||||
})
|
"-=" => Some(|_, args| {
|
||||||
}
|
let (first, second) = args.split_first_mut().expect(BUILTIN);
|
||||||
"-=" => {
|
let mut x = first.write_lock::<ImmutableString>().expect(BUILTIN);
|
||||||
return Some(|_, args| {
|
let y = &*second[0].read_lock::<ImmutableString>().expect(BUILTIN);
|
||||||
let (first, second) = args.split_first_mut().expect(BUILTIN);
|
Ok((*x -= y).into())
|
||||||
let mut x = first.write_lock::<ImmutableString>().expect(BUILTIN);
|
}),
|
||||||
let y = &*second[0].read_lock::<ImmutableString>().expect(BUILTIN);
|
_ => None,
|
||||||
Ok((*x -= y).into())
|
};
|
||||||
})
|
|
||||||
}
|
|
||||||
_ => return None,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
None
|
None
|
||||||
|
@ -618,7 +618,7 @@ impl Engine {
|
|||||||
state: &mut State,
|
state: &mut State,
|
||||||
lib: &[&Module],
|
lib: &[&Module],
|
||||||
fn_name: &str,
|
fn_name: &str,
|
||||||
hash: FnCallHashes,
|
hashes: FnCallHashes,
|
||||||
args: &mut FnCallArgs,
|
args: &mut FnCallArgs,
|
||||||
is_ref: bool,
|
is_ref: bool,
|
||||||
_is_method: bool,
|
_is_method: bool,
|
||||||
@ -689,7 +689,7 @@ impl Engine {
|
|||||||
|
|
||||||
// Scripted function call?
|
// Scripted function call?
|
||||||
#[cfg(not(feature = "no_function"))]
|
#[cfg(not(feature = "no_function"))]
|
||||||
let hash_script = hash.script_hash();
|
let hash_script = hashes.script;
|
||||||
|
|
||||||
#[cfg(not(feature = "no_function"))]
|
#[cfg(not(feature = "no_function"))]
|
||||||
if let Some(f) = hash_script.and_then(|hash| {
|
if let Some(f) = hash_script.and_then(|hash| {
|
||||||
@ -779,7 +779,7 @@ impl Engine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Native function call
|
// 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)
|
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 }
|
// if expr { if_block } else { else_block }
|
||||||
Stmt::If(condition, x, _) => {
|
Stmt::If(condition, x, _) => {
|
||||||
optimize_expr(condition, state, false);
|
optimize_expr(condition, state, false);
|
||||||
let if_block = mem::take(x.0.statements()).into_vec();
|
let if_block = mem::take(x.0.statements_mut()).into_vec();
|
||||||
*x.0.statements() =
|
*x.0.statements_mut() =
|
||||||
optimize_stmt_block(if_block, state, preserve_result, true, false).into();
|
optimize_stmt_block(if_block, state, preserve_result, true, false).into();
|
||||||
let else_block = mem::take(x.1.statements()).into_vec();
|
let else_block = mem::take(x.1.statements_mut()).into_vec();
|
||||||
*x.1.statements() =
|
*x.1.statements_mut() =
|
||||||
optimize_stmt_block(else_block, state, preserve_result, true, false).into();
|
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.0 = Some(condition);
|
||||||
|
|
||||||
*block.1.statements() = optimize_stmt_block(
|
*block.1.statements_mut() = optimize_stmt_block(
|
||||||
mem::take(block.1.statements()).into_vec(),
|
mem::take(block.1.statements_mut()).into_vec(),
|
||||||
state,
|
state,
|
||||||
preserve_result,
|
preserve_result,
|
||||||
true,
|
true,
|
||||||
@ -541,8 +541,8 @@ fn optimize_stmt(stmt: &mut Stmt, state: &mut State, preserve_result: bool) {
|
|||||||
x.0.remove(&key);
|
x.0.remove(&key);
|
||||||
}
|
}
|
||||||
|
|
||||||
let def_block = mem::take(x.1.statements()).into_vec();
|
let def_block = mem::take(x.1.statements_mut()).into_vec();
|
||||||
*x.1.statements() =
|
*x.1.statements_mut() =
|
||||||
optimize_stmt_block(def_block, state, preserve_result, true, false).into();
|
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 }
|
// while expr { block }
|
||||||
Stmt::While(condition, body, _) => {
|
Stmt::While(condition, body, _) => {
|
||||||
optimize_expr(condition, state, false);
|
optimize_expr(condition, state, false);
|
||||||
let block = mem::take(body.statements()).into_vec();
|
let block = mem::take(body.statements_mut()).into_vec();
|
||||||
*body.statements() = optimize_stmt_block(block, state, false, true, false).into();
|
*body.statements_mut() = optimize_stmt_block(block, state, false, true, false).into();
|
||||||
|
|
||||||
if body.len() == 1 {
|
if body.len() == 1 {
|
||||||
match body[0] {
|
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, _) => {
|
| Stmt::Do(body, Expr::BoolConstant(false, _), true, _) => {
|
||||||
state.set_dirty();
|
state.set_dirty();
|
||||||
let block_pos = body.position();
|
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(
|
*stmt = Stmt::Block(
|
||||||
optimize_stmt_block(block, state, false, true, false).into_boxed_slice(),
|
optimize_stmt_block(block, state, false, true, false).into_boxed_slice(),
|
||||||
block_pos,
|
block_pos,
|
||||||
@ -591,14 +591,14 @@ fn optimize_stmt(stmt: &mut Stmt, state: &mut State, preserve_result: bool) {
|
|||||||
// do { block } while|until expr
|
// do { block } while|until expr
|
||||||
Stmt::Do(body, condition, _, _) => {
|
Stmt::Do(body, condition, _, _) => {
|
||||||
optimize_expr(condition, state, false);
|
optimize_expr(condition, state, false);
|
||||||
let block = mem::take(body.statements()).into_vec();
|
let block = mem::take(body.statements_mut()).into_vec();
|
||||||
*body.statements() = optimize_stmt_block(block, state, false, true, false).into();
|
*body.statements_mut() = optimize_stmt_block(block, state, false, true, false).into();
|
||||||
}
|
}
|
||||||
// for id in expr { block }
|
// for id in expr { block }
|
||||||
Stmt::For(iterable, x, _) => {
|
Stmt::For(iterable, x, _) => {
|
||||||
optimize_expr(iterable, state, false);
|
optimize_expr(iterable, state, false);
|
||||||
let body = mem::take(x.2.statements()).into_vec();
|
let body = mem::take(x.2.statements_mut()).into_vec();
|
||||||
*x.2.statements() = optimize_stmt_block(body, state, false, true, false).into();
|
*x.2.statements_mut() = optimize_stmt_block(body, state, false, true, false).into();
|
||||||
}
|
}
|
||||||
// let id = expr;
|
// let id = expr;
|
||||||
Stmt::Let(expr, _, _, _) => optimize_expr(expr, state, false),
|
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 }
|
// try { try_block } catch ( var ) { catch_block }
|
||||||
Stmt::TryCatch(x, _, _) => {
|
Stmt::TryCatch(x, _, _) => {
|
||||||
let try_block = mem::take(x.0.statements()).into_vec();
|
let try_block = mem::take(x.0.statements_mut()).into_vec();
|
||||||
*x.0.statements() = optimize_stmt_block(try_block, state, false, true, false).into();
|
*x.0.statements_mut() =
|
||||||
let catch_block = mem::take(x.2.statements()).into_vec();
|
optimize_stmt_block(try_block, state, false, true, false).into();
|
||||||
*x.2.statements() = optimize_stmt_block(catch_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(...)
|
// func(...)
|
||||||
Stmt::Expr(expr @ Expr::FnCall(_, _)) => {
|
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()) }
|
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
|
// { stmt; ... } - do not count promotion as dirty because it gets turned back into an array
|
||||||
Expr::Stmt(x) => {
|
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
|
// { Stmt(Expr) } - promote
|
||||||
match x.as_mut().as_mut() {
|
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();
|
let arg_types: StaticVec<_> = arg_values.iter().map(Dynamic::type_id).collect();
|
||||||
|
|
||||||
// Search for overloaded operators (can override built-in).
|
// 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])
|
if let Some(mut result) = get_builtin_binary_op_fn(x.name.as_ref(), &arg_values[0], &arg_values[1])
|
||||||
.and_then(|f| {
|
.and_then(|f| {
|
||||||
let ctx = (state.engine, x.name.as_ref(), state.lib).into();
|
let ctx = (state.engine, x.name.as_ref(), state.lib).into();
|
||||||
@ -1136,9 +1138,9 @@ pub fn optimize_into_ast(
|
|||||||
// Optimize the function body
|
// Optimize the function body
|
||||||
let state = &mut State::new(engine, lib2, level);
|
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();
|
optimize_stmt_block(body, state, true, true, true).into();
|
||||||
|
|
||||||
fn_def
|
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);
|
reg_range!(lib | "range" => i8, u8, i16, u16, i32, u32, i64, u64);
|
||||||
|
|
||||||
if cfg!(not(target_arch = "wasm32")) {
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
reg_range!(lib | "range" => i128, u128);
|
reg_range!(lib | "range" => i128, u128);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
reg_range!(lib | step "range" => INT);
|
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);
|
reg_range!(lib | step "range" => i8, u8, i16, u16, i32, u32, i64, u64);
|
||||||
|
|
||||||
if cfg!(not(target_arch = "wasm32")) {
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
reg_range!(lib | step "range" => i128, u128);
|
reg_range!(lib | step "range" => i128, u128);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "no_float"))]
|
#[cfg(not(feature = "no_float"))]
|
||||||
|
@ -478,7 +478,7 @@ fn parse_index_chain(
|
|||||||
let idx_expr = parse_expr(input, state, lib, settings.level_up())?;
|
let idx_expr = parse_expr(input, state, lib, settings.level_up())?;
|
||||||
|
|
||||||
// Check type of indexing - must be integer or string
|
// Check type of indexing - must be integer or string
|
||||||
match &idx_expr {
|
match idx_expr {
|
||||||
Expr::IntegerConstant(_, pos) => match lhs {
|
Expr::IntegerConstant(_, pos) => match lhs {
|
||||||
Expr::IntegerConstant(_, _)
|
Expr::IntegerConstant(_, _)
|
||||||
| Expr::Array(_, _)
|
| Expr::Array(_, _)
|
||||||
@ -489,7 +489,7 @@ fn parse_index_chain(
|
|||||||
return Err(PERR::MalformedIndexExpr(
|
return Err(PERR::MalformedIndexExpr(
|
||||||
"Object map access expects string index, not a number".into(),
|
"Object map access expects string index, not a number".into(),
|
||||||
)
|
)
|
||||||
.into_err(*pos))
|
.into_err(pos))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "no_float"))]
|
#[cfg(not(feature = "no_float"))]
|
||||||
@ -1314,14 +1314,14 @@ fn parse_primary(
|
|||||||
|
|
||||||
// Cache the hash key for namespace-qualified variables
|
// Cache the hash key for namespace-qualified variables
|
||||||
match root_expr {
|
match root_expr {
|
||||||
Expr::Variable(_, _, ref mut 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 &mut x.lhs {
|
Expr::Index(ref mut x, _) | Expr::Dot(ref mut x, _) => match 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()),
|
||||||
_ => None,
|
_ => None,
|
||||||
},
|
},
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
.map(|x| match x.as_mut() {
|
.map(|x| match x {
|
||||||
(_, Some((hash, namespace)), name) => {
|
(_, Some((hash, namespace)), name) => {
|
||||||
*hash = calc_qualified_fn_hash(namespace.iter().map(|v| v.name.as_str()), name, 0);
|
*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));
|
let op_info = op.map(|v| OpAssignment::new(v));
|
||||||
|
|
||||||
match &lhs {
|
match lhs {
|
||||||
// const_expr = rhs
|
// const_expr = rhs
|
||||||
expr if expr.is_constant() => {
|
ref expr if expr.is_constant() => {
|
||||||
Err(PERR::AssignmentToConstant("".into()).into_err(lhs.position()))
|
Err(PERR::AssignmentToConstant("".into()).into_err(lhs.position()))
|
||||||
}
|
}
|
||||||
// var (non-indexed) = rhs
|
// 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))
|
Ok(Stmt::Assignment(Box::new((lhs, op_info, rhs)), op_pos))
|
||||||
}
|
}
|
||||||
// var (indexed) = rhs
|
// var (indexed) = rhs
|
||||||
Expr::Variable(i, var_pos, x) => {
|
Expr::Variable(i, var_pos, ref x) => {
|
||||||
let (index, _, name) = x.as_ref();
|
let (index, _, name) = x.as_ref();
|
||||||
let index = i.map_or_else(
|
let index = i.map_or_else(
|
||||||
|| {
|
|| {
|
||||||
@ -1495,20 +1495,20 @@ fn make_assignment_stmt<'a>(
|
|||||||
}
|
}
|
||||||
// Constant values cannot be assigned to
|
// Constant values cannot be assigned to
|
||||||
AccessMode::ReadOnly => {
|
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
|
// 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(_, _))) {
|
match check_lvalue(&x.rhs, matches!(lhs, Expr::Dot(_, _))) {
|
||||||
None => match &x.lhs {
|
None => match x.lhs {
|
||||||
// var[???] = rhs, var.??? = rhs
|
// var[???] = rhs, var.??? = rhs
|
||||||
Expr::Variable(_, _, _) => {
|
Expr::Variable(_, _, _) => {
|
||||||
Ok(Stmt::Assignment(Box::new((lhs, op_info, rhs)), op_pos))
|
Ok(Stmt::Assignment(Box::new((lhs, op_info, rhs)), op_pos))
|
||||||
}
|
}
|
||||||
// expr[???] = rhs, expr.??? = rhs
|
// expr[???] = rhs, expr.??? = rhs
|
||||||
expr => {
|
ref expr => {
|
||||||
Err(PERR::AssignmentToInvalidLHS("".to_string()).into_err(expr.position()))
|
Err(PERR::AssignmentToInvalidLHS("".to_string()).into_err(expr.position()))
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -2993,7 +2993,7 @@ fn parse_anon_fn(
|
|||||||
#[cfg(not(feature = "unchecked"))]
|
#[cfg(not(feature = "unchecked"))]
|
||||||
settings.ensure_level_within_max_limit(state.max_expr_depth)?;
|
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 input.next().expect(NEVER_ENDS).0 != Token::Or {
|
||||||
if !match_token(input, Token::Pipe).0 {
|
if !match_token(input, Token::Pipe).0 {
|
||||||
@ -3001,12 +3001,12 @@ fn parse_anon_fn(
|
|||||||
match input.next().expect(NEVER_ENDS) {
|
match input.next().expect(NEVER_ENDS) {
|
||||||
(Token::Pipe, _) => break,
|
(Token::Pipe, _) => break,
|
||||||
(Token::Identifier(s), pos) => {
|
(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));
|
return Err(PERR::FnDuplicatedParam("".to_string(), s).into_err(pos));
|
||||||
}
|
}
|
||||||
let s = state.get_identifier(s);
|
let s = state.get_identifier(s);
|
||||||
state.stack.push((s.clone(), AccessMode::ReadWrite));
|
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)),
|
(Token::LexError(err), pos) => return Err(err.into_err(pos)),
|
||||||
(_, pos) => {
|
(_, pos) => {
|
||||||
@ -3040,29 +3040,26 @@ fn parse_anon_fn(
|
|||||||
|
|
||||||
// External variables may need to be processed in a consistent order,
|
// External variables may need to be processed in a consistent order,
|
||||||
// so extract them into a list.
|
// so extract them into a list.
|
||||||
let externals: StaticVec<Identifier> = {
|
#[cfg(not(feature = "no_closure"))]
|
||||||
#[cfg(not(feature = "no_closure"))]
|
let externals: StaticVec<Identifier> = state
|
||||||
{
|
.external_vars
|
||||||
state
|
.iter()
|
||||||
.external_vars
|
.map(|(name, _)| name.clone())
|
||||||
.iter()
|
.collect();
|
||||||
.map(|(name, _)| name.clone())
|
|
||||||
.collect()
|
|
||||||
}
|
|
||||||
#[cfg(feature = "no_closure")]
|
|
||||||
Default::default()
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut params: StaticVec<_> = if cfg!(not(feature = "no_closure")) {
|
let mut params = StaticVec::with_capacity(
|
||||||
externals
|
params_list.len()
|
||||||
.iter()
|
+ if cfg!(not(feature = "no_closure")) {
|
||||||
.cloned()
|
externals.len()
|
||||||
.chain(params.into_iter().map(|(v, _)| v))
|
} else {
|
||||||
.collect()
|
0
|
||||||
} else {
|
},
|
||||||
params.into_iter().map(|(v, _)| v).collect()
|
);
|
||||||
};
|
|
||||||
params.shrink_to_fit();
|
#[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.
|
// Create unique function name by hashing the script body plus the parameters.
|
||||||
let hasher = &mut get_hasher();
|
let hasher = &mut get_hasher();
|
||||||
|
Loading…
Reference in New Issue
Block a user