Merge pull request #399 from schungx/master
Use no-std-compat to build no-std.
This commit is contained in:
commit
b5ade8dad0
@ -4,6 +4,12 @@ Rhai Release Notes
|
|||||||
Version 0.20.1
|
Version 0.20.1
|
||||||
==============
|
==============
|
||||||
|
|
||||||
|
Breaking changes
|
||||||
|
----------------
|
||||||
|
|
||||||
|
* `Dynamic::is_shared` and `Dynamic::is_locked` are removed under the `no_closure` feature. They used to always return `false`.
|
||||||
|
* `Engine::call_fn` now evaluates the `AST` before calling the function.
|
||||||
|
|
||||||
|
|
||||||
Version 0.20.0
|
Version 0.20.0
|
||||||
==============
|
==============
|
||||||
|
@ -41,7 +41,7 @@ internals = [] # expose internal data structures
|
|||||||
unicode-xid-ident = ["unicode-xid"] # allow Unicode Standard Annex #31 for identifiers.
|
unicode-xid-ident = ["unicode-xid"] # allow Unicode Standard Annex #31 for identifiers.
|
||||||
metadata = ["serde_json", "rhai_codegen/metadata"] # enable exporting functions metadata
|
metadata = ["serde_json", "rhai_codegen/metadata"] # enable exporting functions metadata
|
||||||
|
|
||||||
no_std = ["num-traits/libm", "core-error", "libm", "ahash/compile-time-rng"]
|
no_std = ["no-std-compat", "num-traits/libm", "core-error", "libm", "ahash/compile-time-rng"]
|
||||||
|
|
||||||
# compiling for WASM
|
# compiling for WASM
|
||||||
wasm-bindgen = ["instant/wasm-bindgen"]
|
wasm-bindgen = ["instant/wasm-bindgen"]
|
||||||
@ -53,6 +53,12 @@ codegen-units = 1
|
|||||||
#opt-level = "z" # optimize for size
|
#opt-level = "z" # optimize for size
|
||||||
#panic = 'abort' # remove stack backtrace for no-std
|
#panic = 'abort' # remove stack backtrace for no-std
|
||||||
|
|
||||||
|
[dependencies.no-std-compat]
|
||||||
|
version = "0.4"
|
||||||
|
default_features = false
|
||||||
|
features = ["alloc"]
|
||||||
|
optional = true
|
||||||
|
|
||||||
[dependencies.libm]
|
[dependencies.libm]
|
||||||
version = "0.2"
|
version = "0.2"
|
||||||
default_features = false
|
default_features = false
|
||||||
|
45
src/ast.rs
45
src/ast.rs
@ -3,26 +3,28 @@
|
|||||||
use crate::dynamic::{AccessMode, Union};
|
use crate::dynamic::{AccessMode, Union};
|
||||||
use crate::fn_native::shared_make_mut;
|
use crate::fn_native::shared_make_mut;
|
||||||
use crate::module::NamespaceRef;
|
use crate::module::NamespaceRef;
|
||||||
use crate::stdlib::{
|
|
||||||
boxed::Box,
|
|
||||||
collections::BTreeMap,
|
|
||||||
fmt,
|
|
||||||
hash::Hash,
|
|
||||||
iter::empty,
|
|
||||||
num::{NonZeroU8, NonZeroUsize},
|
|
||||||
ops::{Add, AddAssign, Deref, DerefMut},
|
|
||||||
vec,
|
|
||||||
vec::Vec,
|
|
||||||
};
|
|
||||||
use crate::token::Token;
|
use crate::token::Token;
|
||||||
use crate::utils::calc_fn_hash;
|
use crate::utils::calc_fn_hash;
|
||||||
use crate::{
|
use crate::{
|
||||||
Dynamic, FnNamespace, FnPtr, Identifier, ImmutableString, Module, Position, Shared, StaticVec,
|
Dynamic, FnNamespace, FnPtr, Identifier, ImmutableString, Module, Position, Shared, StaticVec,
|
||||||
INT,
|
INT,
|
||||||
};
|
};
|
||||||
|
#[cfg(feature = "no_std")]
|
||||||
|
use std::prelude::v1::*;
|
||||||
|
use std::{
|
||||||
|
collections::BTreeMap,
|
||||||
|
fmt,
|
||||||
|
hash::Hash,
|
||||||
|
iter::empty,
|
||||||
|
num::{NonZeroU8, NonZeroUsize},
|
||||||
|
ops::{Add, AddAssign, Deref, DerefMut},
|
||||||
|
};
|
||||||
|
|
||||||
#[cfg(not(feature = "no_float"))]
|
#[cfg(not(feature = "no_float"))]
|
||||||
use crate::{stdlib::str::FromStr, FLOAT};
|
use std::str::FromStr;
|
||||||
|
|
||||||
|
#[cfg(not(feature = "no_float"))]
|
||||||
|
use crate::FLOAT;
|
||||||
|
|
||||||
#[cfg(not(feature = "no_float"))]
|
#[cfg(not(feature = "no_float"))]
|
||||||
use num_traits::Float;
|
use num_traits::Float;
|
||||||
@ -62,11 +64,11 @@ pub struct ScriptFnDef {
|
|||||||
pub params: StaticVec<Identifier>,
|
pub params: StaticVec<Identifier>,
|
||||||
/// Access to external variables.
|
/// Access to external variables.
|
||||||
#[cfg(not(feature = "no_closure"))]
|
#[cfg(not(feature = "no_closure"))]
|
||||||
pub externals: crate::stdlib::collections::BTreeSet<Identifier>,
|
pub externals: std::collections::BTreeSet<Identifier>,
|
||||||
/// Function doc-comments (if any).
|
/// Function doc-comments (if any).
|
||||||
#[cfg(not(feature = "no_function"))]
|
#[cfg(not(feature = "no_function"))]
|
||||||
#[cfg(feature = "metadata")]
|
#[cfg(feature = "metadata")]
|
||||||
pub comments: StaticVec<crate::stdlib::string::String>,
|
pub comments: StaticVec<std::string::String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for ScriptFnDef {
|
impl fmt::Display for ScriptFnDef {
|
||||||
@ -90,6 +92,7 @@ impl fmt::Display for ScriptFnDef {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// A type containing the metadata of a script-defined function.
|
/// A type containing the metadata of a script-defined function.
|
||||||
|
///
|
||||||
/// Not available under `no_function`.
|
/// Not available under `no_function`.
|
||||||
///
|
///
|
||||||
/// Created by [`AST::iter_functions`].
|
/// Created by [`AST::iter_functions`].
|
||||||
@ -265,6 +268,7 @@ impl AST {
|
|||||||
}
|
}
|
||||||
/// _(INTERNALS)_ Get the internal shared [`Module`] containing all script-defined functions.
|
/// _(INTERNALS)_ Get the internal shared [`Module`] containing all script-defined functions.
|
||||||
/// Exported under the `internals` feature only.
|
/// Exported under the `internals` feature only.
|
||||||
|
///
|
||||||
/// Not available under `no_function`.
|
/// Not available under `no_function`.
|
||||||
#[cfg(feature = "internals")]
|
#[cfg(feature = "internals")]
|
||||||
#[deprecated = "this method is volatile and may change"]
|
#[deprecated = "this method is volatile and may change"]
|
||||||
@ -282,6 +286,7 @@ impl AST {
|
|||||||
}
|
}
|
||||||
/// _(INTERNALS)_ Get the internal [`Module`] containing all script-defined functions.
|
/// _(INTERNALS)_ Get the internal [`Module`] containing all script-defined functions.
|
||||||
/// Exported under the `internals` feature only.
|
/// Exported under the `internals` feature only.
|
||||||
|
///
|
||||||
/// Not available under `no_function`.
|
/// Not available under `no_function`.
|
||||||
#[cfg(feature = "internals")]
|
#[cfg(feature = "internals")]
|
||||||
#[deprecated = "this method is volatile and may change"]
|
#[deprecated = "this method is volatile and may change"]
|
||||||
@ -318,6 +323,7 @@ impl AST {
|
|||||||
}
|
}
|
||||||
/// Clone the [`AST`]'s functions into a new [`AST`].
|
/// Clone the [`AST`]'s functions into a new [`AST`].
|
||||||
/// No statements are cloned.
|
/// No statements are cloned.
|
||||||
|
///
|
||||||
/// Not available under `no_function`.
|
/// Not available under `no_function`.
|
||||||
///
|
///
|
||||||
/// This operation is cheap because functions are shared.
|
/// This operation is cheap because functions are shared.
|
||||||
@ -328,6 +334,7 @@ impl AST {
|
|||||||
}
|
}
|
||||||
/// Clone the [`AST`]'s functions into a new [`AST`] based on a filter predicate.
|
/// Clone the [`AST`]'s functions into a new [`AST`] based on a filter predicate.
|
||||||
/// No statements are cloned.
|
/// No statements are cloned.
|
||||||
|
///
|
||||||
/// Not available under `no_function`.
|
/// Not available under `no_function`.
|
||||||
///
|
///
|
||||||
/// This operation is cheap because functions are shared.
|
/// This operation is cheap because functions are shared.
|
||||||
@ -650,7 +657,7 @@ impl AST {
|
|||||||
}
|
}
|
||||||
/// Iterate through all function definitions.
|
/// Iterate through all function definitions.
|
||||||
///
|
///
|
||||||
/// Not available under [`no_function`].
|
/// Not available under `no_function`.
|
||||||
#[cfg(not(feature = "no_function"))]
|
#[cfg(not(feature = "no_function"))]
|
||||||
#[cfg(not(feature = "no_module"))]
|
#[cfg(not(feature = "no_module"))]
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
@ -1473,7 +1480,7 @@ pub struct FloatWrapper<F>(F);
|
|||||||
#[cfg(not(feature = "no_float"))]
|
#[cfg(not(feature = "no_float"))]
|
||||||
impl Hash for FloatWrapper<FLOAT> {
|
impl Hash for FloatWrapper<FLOAT> {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn hash<H: crate::stdlib::hash::Hasher>(&self, state: &mut H) {
|
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
|
||||||
self.0.to_ne_bytes().hash(state);
|
self.0.to_ne_bytes().hash(state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1495,7 +1502,7 @@ impl<F: Float> AsMut<F> for FloatWrapper<F> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "no_float"))]
|
#[cfg(not(feature = "no_float"))]
|
||||||
impl<F: Float> crate::stdlib::ops::Deref for FloatWrapper<F> {
|
impl<F: Float> std::ops::Deref for FloatWrapper<F> {
|
||||||
type Target = F;
|
type Target = F;
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
@ -1505,7 +1512,7 @@ impl<F: Float> crate::stdlib::ops::Deref for FloatWrapper<F> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "no_float"))]
|
#[cfg(not(feature = "no_float"))]
|
||||||
impl<F: Float> crate::stdlib::ops::DerefMut for FloatWrapper<F> {
|
impl<F: Float> std::ops::DerefMut for FloatWrapper<F> {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||||
&mut self.0
|
&mut self.0
|
||||||
@ -2032,8 +2039,8 @@ mod tests {
|
|||||||
/// This test is to make sure no code changes increase the sizes of critical data structures.
|
/// This test is to make sure no code changes increase the sizes of critical data structures.
|
||||||
#[test]
|
#[test]
|
||||||
fn check_struct_sizes() {
|
fn check_struct_sizes() {
|
||||||
use crate::stdlib::mem::size_of;
|
|
||||||
use crate::*;
|
use crate::*;
|
||||||
|
use std::mem::size_of;
|
||||||
|
|
||||||
assert_eq!(size_of::<Dynamic>(), 16);
|
assert_eq!(size_of::<Dynamic>(), 16);
|
||||||
assert_eq!(size_of::<Option<Dynamic>>(), 16);
|
assert_eq!(size_of::<Option<Dynamic>>(), 16);
|
||||||
|
@ -205,12 +205,17 @@ fn main() {
|
|||||||
.iter_raw()
|
.iter_raw()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.for_each(|(i, (name, constant, value))| {
|
.for_each(|(i, (name, constant, value))| {
|
||||||
|
#[cfg(not(feature = "no_closure"))]
|
||||||
|
let value_is_shared = if value.is_shared() { " (shared" } else { "" };
|
||||||
|
#[cfg(feature = "no_closure")]
|
||||||
|
let value_is_shared = "";
|
||||||
|
|
||||||
println!(
|
println!(
|
||||||
"[{}] {}{}{} = {:?}",
|
"[{}] {}{}{} = {:?}",
|
||||||
i + 1,
|
i + 1,
|
||||||
if constant { "const " } else { "" },
|
if constant { "const " } else { "" },
|
||||||
name,
|
name,
|
||||||
if value.is_shared() { " (shared)" } else { "" },
|
value_is_shared,
|
||||||
*value.read_lock::<Dynamic>().unwrap(),
|
*value.read_lock::<Dynamic>().unwrap(),
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
|
@ -2,15 +2,15 @@
|
|||||||
|
|
||||||
use crate::fn_native::SendSync;
|
use crate::fn_native::SendSync;
|
||||||
use crate::r#unsafe::{unsafe_cast_box, unsafe_try_cast};
|
use crate::r#unsafe::{unsafe_cast_box, unsafe_try_cast};
|
||||||
use crate::stdlib::{
|
use crate::{FnPtr, ImmutableString, INT};
|
||||||
|
#[cfg(feature = "no_std")]
|
||||||
|
use std::prelude::v1::*;
|
||||||
|
use std::{
|
||||||
any::{type_name, Any, TypeId},
|
any::{type_name, Any, TypeId},
|
||||||
boxed::Box,
|
|
||||||
fmt,
|
fmt,
|
||||||
hash::{Hash, Hasher},
|
hash::{Hash, Hasher},
|
||||||
ops::{Deref, DerefMut},
|
ops::{Deref, DerefMut},
|
||||||
string::String,
|
|
||||||
};
|
};
|
||||||
use crate::{FnPtr, ImmutableString, INT};
|
|
||||||
|
|
||||||
#[cfg(not(feature = "no_float"))]
|
#[cfg(not(feature = "no_float"))]
|
||||||
use crate::{ast::FloatWrapper, FLOAT};
|
use crate::{ast::FloatWrapper, FLOAT};
|
||||||
@ -26,7 +26,7 @@ use crate::Map;
|
|||||||
|
|
||||||
#[cfg(not(feature = "no_std"))]
|
#[cfg(not(feature = "no_std"))]
|
||||||
#[cfg(not(any(target_arch = "wasm32", target_arch = "wasm64")))]
|
#[cfg(not(any(target_arch = "wasm32", target_arch = "wasm64")))]
|
||||||
use crate::stdlib::time::Instant;
|
use std::time::Instant;
|
||||||
|
|
||||||
use fmt::Debug;
|
use fmt::Debug;
|
||||||
#[cfg(not(feature = "no_std"))]
|
#[cfg(not(feature = "no_std"))]
|
||||||
@ -35,7 +35,7 @@ use instant::Instant;
|
|||||||
|
|
||||||
mod private {
|
mod private {
|
||||||
use crate::fn_native::SendSync;
|
use crate::fn_native::SendSync;
|
||||||
use crate::stdlib::any::Any;
|
use std::any::Any;
|
||||||
|
|
||||||
/// A sealed trait that prevents other crates from implementing [`Variant`].
|
/// A sealed trait that prevents other crates from implementing [`Variant`].
|
||||||
pub trait Sealed {}
|
pub trait Sealed {}
|
||||||
@ -199,11 +199,11 @@ enum DynamicReadLockInner<'d, T: Variant + Clone> {
|
|||||||
/// A read guard to a shared [`RefCell`][std::cell::RefCell].
|
/// A read guard to a shared [`RefCell`][std::cell::RefCell].
|
||||||
#[cfg(not(feature = "no_closure"))]
|
#[cfg(not(feature = "no_closure"))]
|
||||||
#[cfg(not(feature = "sync"))]
|
#[cfg(not(feature = "sync"))]
|
||||||
Guard(crate::stdlib::cell::Ref<'d, Dynamic>),
|
Guard(std::cell::Ref<'d, Dynamic>),
|
||||||
/// A read guard to a shared [`RwLock`][std::sync::RwLock].
|
/// A read guard to a shared [`RwLock`][std::sync::RwLock].
|
||||||
#[cfg(not(feature = "no_closure"))]
|
#[cfg(not(feature = "no_closure"))]
|
||||||
#[cfg(feature = "sync")]
|
#[cfg(feature = "sync")]
|
||||||
Guard(crate::stdlib::sync::RwLockReadGuard<'d, Dynamic>),
|
Guard(std::sync::RwLockReadGuard<'d, Dynamic>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, T: Variant + Clone> Deref for DynamicReadLock<'d, T> {
|
impl<'d, T: Variant + Clone> Deref for DynamicReadLock<'d, T> {
|
||||||
@ -236,11 +236,11 @@ enum DynamicWriteLockInner<'d, T: Variant + Clone> {
|
|||||||
/// A write guard to a shared [`RefCell`][std::cell::RefCell].
|
/// A write guard to a shared [`RefCell`][std::cell::RefCell].
|
||||||
#[cfg(not(feature = "no_closure"))]
|
#[cfg(not(feature = "no_closure"))]
|
||||||
#[cfg(not(feature = "sync"))]
|
#[cfg(not(feature = "sync"))]
|
||||||
Guard(crate::stdlib::cell::RefMut<'d, Dynamic>),
|
Guard(std::cell::RefMut<'d, Dynamic>),
|
||||||
/// A write guard to a shared [`RwLock`][std::sync::RwLock].
|
/// A write guard to a shared [`RwLock`][std::sync::RwLock].
|
||||||
#[cfg(not(feature = "no_closure"))]
|
#[cfg(not(feature = "no_closure"))]
|
||||||
#[cfg(feature = "sync")]
|
#[cfg(feature = "sync")]
|
||||||
Guard(crate::stdlib::sync::RwLockWriteGuard<'d, Dynamic>),
|
Guard(std::sync::RwLockWriteGuard<'d, Dynamic>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, T: Variant + Clone> Deref for DynamicWriteLock<'d, T> {
|
impl<'d, T: Variant + Clone> Deref for DynamicWriteLock<'d, T> {
|
||||||
@ -281,7 +281,8 @@ impl Dynamic {
|
|||||||
}
|
}
|
||||||
/// Is the value held by this [`Dynamic`] shared?
|
/// Is the value held by this [`Dynamic`] shared?
|
||||||
///
|
///
|
||||||
/// Always [`false`] under the `no_closure` feature.
|
/// Not available under `no_closure`.
|
||||||
|
#[cfg(not(feature = "no_closure"))]
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn is_shared(&self) -> bool {
|
pub fn is_shared(&self) -> bool {
|
||||||
#[cfg(not(feature = "no_closure"))]
|
#[cfg(not(feature = "no_closure"))]
|
||||||
@ -948,10 +949,6 @@ impl Dynamic {
|
|||||||
/// values.
|
/// values.
|
||||||
///
|
///
|
||||||
/// If the [`Dynamic`] value is already shared, this method returns itself.
|
/// If the [`Dynamic`] value is already shared, this method returns itself.
|
||||||
///
|
|
||||||
/// # Panics
|
|
||||||
///
|
|
||||||
/// Panics under the `no_closure` feature.
|
|
||||||
#[cfg(not(feature = "no_closure"))]
|
#[cfg(not(feature = "no_closure"))]
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn into_shared(self) -> Self {
|
pub fn into_shared(self) -> Self {
|
||||||
@ -1122,12 +1119,15 @@ impl Dynamic {
|
|||||||
/// ```
|
/// ```
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn cast<T: Variant + Clone>(self) -> T {
|
pub fn cast<T: Variant + Clone>(self) -> T {
|
||||||
|
#[cfg(not(feature = "no_closure"))]
|
||||||
let self_type_name = if self.is_shared() {
|
let self_type_name = if self.is_shared() {
|
||||||
// Avoid panics/deadlocks with shared values
|
// Avoid panics/deadlocks with shared values
|
||||||
"<shared>"
|
"<shared>"
|
||||||
} else {
|
} else {
|
||||||
self.type_name()
|
self.type_name()
|
||||||
};
|
};
|
||||||
|
#[cfg(feature = "no_closure")]
|
||||||
|
let self_type_name = self.type_name();
|
||||||
|
|
||||||
self.try_cast::<T>().unwrap_or_else(|| {
|
self.try_cast::<T>().unwrap_or_else(|| {
|
||||||
panic!(
|
panic!(
|
||||||
@ -1233,7 +1233,7 @@ impl Dynamic {
|
|||||||
pub(crate) fn flatten_in_place(&mut self) {
|
pub(crate) fn flatten_in_place(&mut self) {
|
||||||
#[cfg(not(feature = "no_closure"))]
|
#[cfg(not(feature = "no_closure"))]
|
||||||
match self.0 {
|
match self.0 {
|
||||||
Union::Shared(_, _) => match crate::stdlib::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| {
|
|cell| {
|
||||||
@ -1259,11 +1259,14 @@ impl Dynamic {
|
|||||||
}
|
}
|
||||||
/// Is the [`Dynamic`] a shared value that is locked?
|
/// Is the [`Dynamic`] a shared value that is locked?
|
||||||
///
|
///
|
||||||
|
/// Not available under `no_closure`.
|
||||||
|
///
|
||||||
/// ## Note
|
/// ## Note
|
||||||
///
|
///
|
||||||
/// Under the `sync` feature, shared values use [`RwLock`][std::sync::RwLock] and they are never locked.
|
/// Under the `sync` feature, shared values use [`RwLock`][std::sync::RwLock] and they are never locked.
|
||||||
/// Access just waits until the [`RwLock`][std::sync::RwLock] is released.
|
/// Access just waits until the [`RwLock`][std::sync::RwLock] is released.
|
||||||
/// So this method always returns [`false`] under [`Sync`].
|
/// So this method always returns [`false`] under [`Sync`].
|
||||||
|
#[cfg(not(feature = "no_closure"))]
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn is_locked(&self) -> bool {
|
pub fn is_locked(&self) -> bool {
|
||||||
#[cfg(not(feature = "no_closure"))]
|
#[cfg(not(feature = "no_closure"))]
|
||||||
@ -1714,13 +1717,13 @@ impl From<&ImmutableString> for Dynamic {
|
|||||||
impl From<&crate::Identifier> for Dynamic {
|
impl From<&crate::Identifier> for Dynamic {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn from(value: &crate::Identifier) -> Self {
|
fn from(value: &crate::Identifier) -> Self {
|
||||||
crate::stdlib::string::ToString::to_string(value).into()
|
std::string::ToString::to_string(value).into()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[cfg(not(feature = "no_index"))]
|
#[cfg(not(feature = "no_index"))]
|
||||||
impl<T: Variant + Clone> From<crate::stdlib::vec::Vec<T>> for Dynamic {
|
impl<T: Variant + Clone> From<std::vec::Vec<T>> for Dynamic {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn from(value: crate::stdlib::vec::Vec<T>) -> Self {
|
fn from(value: std::vec::Vec<T>) -> Self {
|
||||||
Self(Union::Array(
|
Self(Union::Array(
|
||||||
Box::new(value.into_iter().map(Dynamic::from).collect()),
|
Box::new(value.into_iter().map(Dynamic::from).collect()),
|
||||||
AccessMode::ReadWrite,
|
AccessMode::ReadWrite,
|
||||||
@ -1738,7 +1741,7 @@ impl<T: Variant + Clone> From<&[T]> for Dynamic {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[cfg(not(feature = "no_index"))]
|
#[cfg(not(feature = "no_index"))]
|
||||||
impl<T: Variant + Clone> crate::stdlib::iter::FromIterator<T> for Dynamic {
|
impl<T: Variant + Clone> std::iter::FromIterator<T> for Dynamic {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn from_iter<X: IntoIterator<Item = T>>(iter: X) -> Self {
|
fn from_iter<X: IntoIterator<Item = T>>(iter: X) -> Self {
|
||||||
Self(Union::Array(
|
Self(Union::Array(
|
||||||
@ -1749,11 +1752,11 @@ impl<T: Variant + Clone> crate::stdlib::iter::FromIterator<T> for Dynamic {
|
|||||||
}
|
}
|
||||||
#[cfg(not(feature = "no_object"))]
|
#[cfg(not(feature = "no_object"))]
|
||||||
#[cfg(not(feature = "no_std"))]
|
#[cfg(not(feature = "no_std"))]
|
||||||
impl<K: Into<crate::Identifier>, T: Variant + Clone> From<crate::stdlib::collections::HashMap<K, T>>
|
impl<K: Into<crate::Identifier>, T: Variant + Clone> From<std::collections::HashMap<K, T>>
|
||||||
for Dynamic
|
for Dynamic
|
||||||
{
|
{
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn from(value: crate::stdlib::collections::HashMap<K, T>) -> Self {
|
fn from(value: std::collections::HashMap<K, T>) -> Self {
|
||||||
Self(Union::Map(
|
Self(Union::Map(
|
||||||
Box::new(
|
Box::new(
|
||||||
value
|
value
|
||||||
@ -1766,11 +1769,11 @@ impl<K: Into<crate::Identifier>, T: Variant + Clone> From<crate::stdlib::collect
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[cfg(not(feature = "no_object"))]
|
#[cfg(not(feature = "no_object"))]
|
||||||
impl<K: Into<crate::Identifier>, T: Variant + Clone>
|
impl<K: Into<crate::Identifier>, T: Variant + Clone> From<std::collections::BTreeMap<K, T>>
|
||||||
From<crate::stdlib::collections::BTreeMap<K, T>> for Dynamic
|
for Dynamic
|
||||||
{
|
{
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn from(value: crate::stdlib::collections::BTreeMap<K, T>) -> Self {
|
fn from(value: std::collections::BTreeMap<K, T>) -> Self {
|
||||||
Self(Union::Map(
|
Self(Union::Map(
|
||||||
Box::new(
|
Box::new(
|
||||||
value
|
value
|
||||||
|
120
src/engine.rs
120
src/engine.rs
@ -10,27 +10,26 @@ use crate::module::NamespaceRef;
|
|||||||
use crate::optimize::OptimizationLevel;
|
use crate::optimize::OptimizationLevel;
|
||||||
use crate::packages::{Package, StandardPackage};
|
use crate::packages::{Package, StandardPackage};
|
||||||
use crate::r#unsafe::unsafe_cast_var_name_to_lifetime;
|
use crate::r#unsafe::unsafe_cast_var_name_to_lifetime;
|
||||||
use crate::stdlib::{
|
|
||||||
any::{type_name, TypeId},
|
|
||||||
borrow::Cow,
|
|
||||||
boxed::Box,
|
|
||||||
collections::{BTreeMap, BTreeSet},
|
|
||||||
fmt, format,
|
|
||||||
hash::{Hash, Hasher},
|
|
||||||
num::{NonZeroU8, NonZeroUsize},
|
|
||||||
ops::DerefMut,
|
|
||||||
string::{String, ToString},
|
|
||||||
vec::Vec,
|
|
||||||
};
|
|
||||||
use crate::syntax::CustomSyntax;
|
use crate::syntax::CustomSyntax;
|
||||||
use crate::utils::get_hasher;
|
use crate::utils::get_hasher;
|
||||||
use crate::{
|
use crate::{
|
||||||
Dynamic, EvalAltResult, FnPtr, Identifier, ImmutableString, Module, Position, RhaiResult,
|
Dynamic, EvalAltResult, FnPtr, Identifier, ImmutableString, Module, Position, RhaiResult,
|
||||||
Scope, Shared, StaticVec,
|
Scope, Shared, StaticVec,
|
||||||
};
|
};
|
||||||
|
#[cfg(feature = "no_std")]
|
||||||
|
use std::prelude::v1::*;
|
||||||
|
use std::{
|
||||||
|
any::{type_name, TypeId},
|
||||||
|
borrow::Cow,
|
||||||
|
collections::{BTreeMap, BTreeSet},
|
||||||
|
fmt,
|
||||||
|
hash::{Hash, Hasher},
|
||||||
|
num::{NonZeroU8, NonZeroUsize},
|
||||||
|
ops::{Deref, DerefMut},
|
||||||
|
};
|
||||||
|
|
||||||
#[cfg(not(feature = "no_index"))]
|
#[cfg(not(feature = "no_index"))]
|
||||||
use crate::{calc_fn_hash, stdlib::iter::empty, Array};
|
use crate::{calc_fn_hash, Array};
|
||||||
|
|
||||||
#[cfg(not(feature = "no_object"))]
|
#[cfg(not(feature = "no_object"))]
|
||||||
use crate::Map;
|
use crate::Map;
|
||||||
@ -344,7 +343,7 @@ impl<'a> Target<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
/// Is the `Target` a shared value?
|
/// Is the `Target` a shared value?
|
||||||
#[allow(dead_code)]
|
#[cfg(not(feature = "no_closure"))]
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn is_shared(&self) -> bool {
|
pub fn is_shared(&self) -> bool {
|
||||||
match self {
|
match self {
|
||||||
@ -467,9 +466,11 @@ impl<'a> From<&'a mut Dynamic> for Target<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AsRef<Dynamic> for Target<'_> {
|
impl Deref for Target<'_> {
|
||||||
|
type Target = Dynamic;
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn as_ref(&self) -> &Dynamic {
|
fn deref(&self) -> &Dynamic {
|
||||||
match self {
|
match self {
|
||||||
Self::Ref(r) => *r,
|
Self::Ref(r) => *r,
|
||||||
#[cfg(not(feature = "no_closure"))]
|
#[cfg(not(feature = "no_closure"))]
|
||||||
@ -482,9 +483,16 @@ impl AsRef<Dynamic> for Target<'_> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AsMut<Dynamic> for Target<'_> {
|
impl AsRef<Dynamic> for Target<'_> {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn as_mut(&mut self) -> &mut Dynamic {
|
fn as_ref(&self) -> &Dynamic {
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DerefMut for Target<'_> {
|
||||||
|
#[inline(always)]
|
||||||
|
fn deref_mut(&mut self) -> &mut Dynamic {
|
||||||
match self {
|
match self {
|
||||||
Self::Ref(r) => *r,
|
Self::Ref(r) => *r,
|
||||||
#[cfg(not(feature = "no_closure"))]
|
#[cfg(not(feature = "no_closure"))]
|
||||||
@ -497,6 +505,13 @@ impl AsMut<Dynamic> for Target<'_> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl AsMut<Dynamic> for Target<'_> {
|
||||||
|
#[inline(always)]
|
||||||
|
fn as_mut(&mut self) -> &mut Dynamic {
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<T: Into<Dynamic>> From<T> for Target<'_> {
|
impl<T: Into<Dynamic>> From<T> for Target<'_> {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn from(value: T) -> Self {
|
fn from(value: T) -> Self {
|
||||||
@ -600,7 +615,7 @@ pub struct Limits {
|
|||||||
#[cfg(not(feature = "no_function"))]
|
#[cfg(not(feature = "no_function"))]
|
||||||
pub max_function_expr_depth: Option<NonZeroUsize>,
|
pub max_function_expr_depth: Option<NonZeroUsize>,
|
||||||
/// Maximum number of operations allowed to run.
|
/// Maximum number of operations allowed to run.
|
||||||
pub max_operations: Option<crate::stdlib::num::NonZeroU64>,
|
pub max_operations: Option<std::num::NonZeroU64>,
|
||||||
/// Maximum number of [modules][Module] allowed to load.
|
/// Maximum number of [modules][Module] allowed to load.
|
||||||
///
|
///
|
||||||
/// Set to zero to effectively disable loading any [module][Module].
|
/// Set to zero to effectively disable loading any [module][Module].
|
||||||
@ -1105,8 +1120,6 @@ impl Engine {
|
|||||||
// Pop the last index value
|
// Pop the last index value
|
||||||
let idx_val = idx_values.pop().unwrap();
|
let idx_val = idx_values.pop().unwrap();
|
||||||
|
|
||||||
let target_val = target.as_mut();
|
|
||||||
|
|
||||||
match chain_type {
|
match chain_type {
|
||||||
#[cfg(not(feature = "no_index"))]
|
#[cfg(not(feature = "no_index"))]
|
||||||
ChainType::Index => {
|
ChainType::Index => {
|
||||||
@ -1118,8 +1131,7 @@ impl Engine {
|
|||||||
let idx_pos = x.lhs.position();
|
let idx_pos = x.lhs.position();
|
||||||
let idx_val = idx_val.as_index_value();
|
let idx_val = idx_val.as_index_value();
|
||||||
let obj_ptr = &mut self.get_indexed_mut(
|
let obj_ptr = &mut self.get_indexed_mut(
|
||||||
mods, state, lib, target_val, idx_val, idx_pos, false, is_ref, true,
|
mods, state, lib, target, idx_val, idx_pos, false, is_ref, true, level,
|
||||||
level,
|
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
self.eval_dot_index_chain_helper(
|
self.eval_dot_index_chain_helper(
|
||||||
@ -1137,7 +1149,7 @@ impl Engine {
|
|||||||
|
|
||||||
// `call_setter` is introduced to bypass double mutable borrowing of target
|
// `call_setter` is introduced to bypass double mutable borrowing of target
|
||||||
let _call_setter = match self.get_indexed_mut(
|
let _call_setter = match self.get_indexed_mut(
|
||||||
mods, state, lib, target_val, idx_val, pos, true, is_ref, false, level,
|
mods, state, lib, target, idx_val, pos, true, is_ref, false, level,
|
||||||
) {
|
) {
|
||||||
// Indexed value is a reference - update directly
|
// Indexed value is a reference - update directly
|
||||||
Ok(obj_ptr) => {
|
Ok(obj_ptr) => {
|
||||||
@ -1158,12 +1170,15 @@ impl Engine {
|
|||||||
|
|
||||||
#[cfg(not(feature = "no_index"))]
|
#[cfg(not(feature = "no_index"))]
|
||||||
if let Some(mut new_val) = _call_setter {
|
if let Some(mut new_val) = _call_setter {
|
||||||
let val_type_name = target_val.type_name();
|
let val_type_name = target.type_name();
|
||||||
let ((_, val_pos), _) = new_val;
|
let ((_, val_pos), _) = new_val;
|
||||||
|
|
||||||
let hash_set =
|
let hash_set = FnCallHash::from_native(calc_fn_hash(
|
||||||
FnCallHash::from_native(calc_fn_hash(empty(), FN_IDX_SET, 3));
|
std::iter::empty(),
|
||||||
let args = &mut [target_val, &mut idx_val2, &mut (new_val.0).0];
|
FN_IDX_SET,
|
||||||
|
3,
|
||||||
|
));
|
||||||
|
let args = &mut [target, &mut idx_val2, &mut (new_val.0).0];
|
||||||
|
|
||||||
self.exec_fn_call(
|
self.exec_fn_call(
|
||||||
mods, state, lib, FN_IDX_SET, hash_set, args, is_ref, true,
|
mods, state, lib, FN_IDX_SET, hash_set, args, is_ref, true,
|
||||||
@ -1188,7 +1203,7 @@ impl Engine {
|
|||||||
_ => {
|
_ => {
|
||||||
let idx_val = idx_val.as_index_value();
|
let idx_val = idx_val.as_index_value();
|
||||||
self.get_indexed_mut(
|
self.get_indexed_mut(
|
||||||
mods, state, lib, target_val, idx_val, pos, false, is_ref, true, level,
|
mods, state, lib, target, idx_val, pos, false, is_ref, true, level,
|
||||||
)
|
)
|
||||||
.map(|v| (v.take_or_clone(), false))
|
.map(|v| (v.take_or_clone(), false))
|
||||||
}
|
}
|
||||||
@ -1215,11 +1230,11 @@ impl Engine {
|
|||||||
unreachable!("function call in dot chain should not be namespace-qualified")
|
unreachable!("function call in dot chain should not be namespace-qualified")
|
||||||
}
|
}
|
||||||
// {xxx:map}.id op= ???
|
// {xxx:map}.id op= ???
|
||||||
Expr::Property(x) if target_val.is::<Map>() && new_val.is_some() => {
|
Expr::Property(x) if target.is::<Map>() && new_val.is_some() => {
|
||||||
let Ident { name, pos, .. } = &x.2;
|
let Ident { name, pos, .. } = &x.2;
|
||||||
let index = name.into();
|
let index = name.into();
|
||||||
let val = self.get_indexed_mut(
|
let val = self.get_indexed_mut(
|
||||||
mods, state, lib, target_val, index, *pos, true, is_ref, false, level,
|
mods, state, lib, target, index, *pos, true, is_ref, false, level,
|
||||||
)?;
|
)?;
|
||||||
let ((new_val, new_pos), (op_info, op_pos)) = new_val.unwrap();
|
let ((new_val, new_pos), (op_info, op_pos)) = new_val.unwrap();
|
||||||
self.eval_op_assignment(
|
self.eval_op_assignment(
|
||||||
@ -1228,11 +1243,11 @@ impl Engine {
|
|||||||
Ok((Dynamic::UNIT, true))
|
Ok((Dynamic::UNIT, true))
|
||||||
}
|
}
|
||||||
// {xxx:map}.id
|
// {xxx:map}.id
|
||||||
Expr::Property(x) if target_val.is::<Map>() => {
|
Expr::Property(x) if target.is::<Map>() => {
|
||||||
let Ident { name, pos, .. } = &x.2;
|
let Ident { name, pos, .. } = &x.2;
|
||||||
let index = name.into();
|
let index = name.into();
|
||||||
let val = self.get_indexed_mut(
|
let val = self.get_indexed_mut(
|
||||||
mods, state, lib, target_val, index, *pos, false, is_ref, false, level,
|
mods, state, lib, target, index, *pos, false, is_ref, false, level,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
Ok((val.take_or_clone(), false))
|
Ok((val.take_or_clone(), false))
|
||||||
@ -1269,7 +1284,7 @@ impl Engine {
|
|||||||
Expr::Property(x) => {
|
Expr::Property(x) => {
|
||||||
let ((getter, hash_get), _, Ident { pos, .. }) = x.as_ref();
|
let ((getter, hash_get), _, Ident { pos, .. }) = x.as_ref();
|
||||||
let hash = FnCallHash::from_native(*hash_get);
|
let hash = FnCallHash::from_native(*hash_get);
|
||||||
let mut args = [target_val];
|
let mut args = [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, &mut args, is_ref, true, *pos, None,
|
||||||
level,
|
level,
|
||||||
@ -1277,13 +1292,13 @@ impl Engine {
|
|||||||
.map(|(v, _)| (v, false))
|
.map(|(v, _)| (v, false))
|
||||||
}
|
}
|
||||||
// {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_val.is::<Map>() => {
|
Expr::Index(x, x_pos) | Expr::Dot(x, x_pos) if target.is::<Map>() => {
|
||||||
let mut val = match &x.lhs {
|
let mut val = match &x.lhs {
|
||||||
Expr::Property(p) => {
|
Expr::Property(p) => {
|
||||||
let Ident { name, pos, .. } = &p.2;
|
let Ident { name, pos, .. } = &p.2;
|
||||||
let index = name.into();
|
let index = name.into();
|
||||||
self.get_indexed_mut(
|
self.get_indexed_mut(
|
||||||
mods, state, lib, target_val, index, *pos, false, is_ref, true,
|
mods, state, lib, target, index, *pos, false, is_ref, true,
|
||||||
level,
|
level,
|
||||||
)?
|
)?
|
||||||
}
|
}
|
||||||
@ -1319,7 +1334,7 @@ impl Engine {
|
|||||||
p.as_ref();
|
p.as_ref();
|
||||||
let hash_get = FnCallHash::from_native(*hash_get);
|
let hash_get = FnCallHash::from_native(*hash_get);
|
||||||
let hash_set = FnCallHash::from_native(*hash_set);
|
let hash_set = FnCallHash::from_native(*hash_set);
|
||||||
let arg_values = &mut [target_val, &mut Default::default()];
|
let arg_values = &mut [target.as_mut(), &mut Default::default()];
|
||||||
let args = &mut arg_values[..1];
|
let args = &mut arg_values[..1];
|
||||||
let (mut val, updated) = self.exec_fn_call(
|
let (mut val, updated) = self.exec_fn_call(
|
||||||
mods, state, lib, getter, hash_get, args, is_ref, true, *pos,
|
mods, state, lib, getter, hash_get, args, is_ref, true, *pos,
|
||||||
@ -1432,7 +1447,7 @@ impl Engine {
|
|||||||
self.search_namespace(scope, mods, state, lib, this_ptr, lhs)?;
|
self.search_namespace(scope, mods, state, lib, this_ptr, lhs)?;
|
||||||
|
|
||||||
// Constants cannot be modified
|
// Constants cannot be modified
|
||||||
if target.as_ref().is_read_only() && new_val.is_some() {
|
if target.is_read_only() && new_val.is_some() {
|
||||||
return EvalAltResult::ErrorAssignmentToConstant(x.2.to_string(), pos).into();
|
return EvalAltResult::ErrorAssignmentToConstant(x.2.to_string(), pos).into();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1675,7 +1690,8 @@ impl Engine {
|
|||||||
_ if _indexers => {
|
_ if _indexers => {
|
||||||
let type_name = target.type_name();
|
let type_name = target.type_name();
|
||||||
let args = &mut [target, &mut _idx];
|
let args = &mut [target, &mut _idx];
|
||||||
let hash_get = FnCallHash::from_native(calc_fn_hash(empty(), FN_IDX_GET, 2));
|
let hash_get =
|
||||||
|
FnCallHash::from_native(calc_fn_hash(std::iter::empty(), FN_IDX_GET, 2));
|
||||||
self.exec_fn_call(
|
self.exec_fn_call(
|
||||||
_mods, state, _lib, FN_IDX_GET, hash_get, args, _is_ref, true, idx_pos, None,
|
_mods, state, _lib, FN_IDX_GET, hash_get, args, _is_ref, true, idx_pos, None,
|
||||||
_level,
|
_level,
|
||||||
@ -1977,7 +1993,7 @@ impl Engine {
|
|||||||
mut new_value: Dynamic,
|
mut new_value: Dynamic,
|
||||||
new_value_pos: Position,
|
new_value_pos: Position,
|
||||||
) -> Result<(), Box<EvalAltResult>> {
|
) -> Result<(), Box<EvalAltResult>> {
|
||||||
if target.as_ref().is_read_only() {
|
if target.is_read_only() {
|
||||||
unreachable!("LHS should not be read-only");
|
unreachable!("LHS should not be read-only");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1990,11 +2006,16 @@ impl Engine {
|
|||||||
let mut lock_guard;
|
let mut lock_guard;
|
||||||
let lhs_ptr_inner;
|
let lhs_ptr_inner;
|
||||||
|
|
||||||
if cfg!(not(feature = "no_closure")) && target.is_shared() {
|
#[cfg(not(feature = "no_closure"))]
|
||||||
lock_guard = target.as_mut().write_lock::<Dynamic>().unwrap();
|
let target_is_shared = target.is_shared();
|
||||||
lhs_ptr_inner = lock_guard.deref_mut();
|
#[cfg(feature = "no_closure")]
|
||||||
|
let target_is_shared = false;
|
||||||
|
|
||||||
|
if target_is_shared {
|
||||||
|
lock_guard = target.write_lock::<Dynamic>().unwrap();
|
||||||
|
lhs_ptr_inner = &mut *lock_guard;
|
||||||
} else {
|
} else {
|
||||||
lhs_ptr_inner = target.as_mut();
|
lhs_ptr_inner = &mut *target;
|
||||||
}
|
}
|
||||||
|
|
||||||
let hash = hash_op_assign;
|
let hash = hash_op_assign;
|
||||||
@ -2070,7 +2091,7 @@ impl Engine {
|
|||||||
|
|
||||||
self.inc_operations(state, pos)?;
|
self.inc_operations(state, pos)?;
|
||||||
|
|
||||||
if lhs_ptr.as_ref().is_read_only() {
|
if lhs_ptr.is_read_only() {
|
||||||
// Assignment to constant variable
|
// Assignment to constant variable
|
||||||
EvalAltResult::ErrorAssignmentToConstant(
|
EvalAltResult::ErrorAssignmentToConstant(
|
||||||
lhs_expr.get_variable_name(false).unwrap().to_string(),
|
lhs_expr.get_variable_name(false).unwrap().to_string(),
|
||||||
@ -2314,7 +2335,12 @@ impl Engine {
|
|||||||
let loop_var = scope.get_mut_by_index(index);
|
let loop_var = scope.get_mut_by_index(index);
|
||||||
let value = iter_value.flatten();
|
let value = iter_value.flatten();
|
||||||
|
|
||||||
if cfg!(not(feature = "no_closure")) && loop_var.is_shared() {
|
#[cfg(not(feature = "no_closure"))]
|
||||||
|
let loop_var_is_shared = loop_var.is_shared();
|
||||||
|
#[cfg(feature = "no_closure")]
|
||||||
|
let loop_var_is_shared = false;
|
||||||
|
|
||||||
|
if loop_var_is_shared {
|
||||||
*loop_var.write_lock().unwrap() = value;
|
*loop_var.write_lock().unwrap() = value;
|
||||||
} else {
|
} else {
|
||||||
*loop_var = value;
|
*loop_var = value;
|
||||||
@ -2571,7 +2597,7 @@ impl Engine {
|
|||||||
|
|
||||||
if !val.is_shared() {
|
if !val.is_shared() {
|
||||||
// Replace the variable with a shared value.
|
// Replace the variable with a shared value.
|
||||||
*val = crate::stdlib::mem::take(val).into_shared();
|
*val = std::mem::take(val).into_shared();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(Dynamic::UNIT)
|
Ok(Dynamic::UNIT)
|
||||||
|
@ -6,15 +6,13 @@ use crate::fn_native::{FnCallArgs, SendSync};
|
|||||||
use crate::fn_register::RegisterNativeFunction;
|
use crate::fn_register::RegisterNativeFunction;
|
||||||
use crate::optimize::OptimizationLevel;
|
use crate::optimize::OptimizationLevel;
|
||||||
use crate::parser::ParseState;
|
use crate::parser::ParseState;
|
||||||
use crate::stdlib::{
|
|
||||||
any::{type_name, TypeId},
|
|
||||||
boxed::Box,
|
|
||||||
string::String,
|
|
||||||
};
|
|
||||||
use crate::{
|
use crate::{
|
||||||
scope::Scope, Dynamic, Engine, EvalAltResult, FnAccess, FnNamespace, Identifier, Module,
|
scope::Scope, Dynamic, Engine, EvalAltResult, FnAccess, FnNamespace, Identifier, Module,
|
||||||
NativeCallContext, ParseError, Position, RhaiResult, Shared, AST,
|
NativeCallContext, ParseError, Position, RhaiResult, Shared, AST,
|
||||||
};
|
};
|
||||||
|
use std::any::{type_name, TypeId};
|
||||||
|
#[cfg(feature = "no_std")]
|
||||||
|
use std::prelude::v1::*;
|
||||||
|
|
||||||
#[cfg(not(feature = "no_index"))]
|
#[cfg(not(feature = "no_index"))]
|
||||||
use crate::Array;
|
use crate::Array;
|
||||||
@ -61,7 +59,7 @@ impl Engine {
|
|||||||
#[cfg(feature = "metadata")]
|
#[cfg(feature = "metadata")]
|
||||||
let mut param_type_names: crate::StaticVec<_> = F::param_names()
|
let mut param_type_names: crate::StaticVec<_> = F::param_names()
|
||||||
.iter()
|
.iter()
|
||||||
.map(|ty| crate::stdlib::format!("_: {}", self.map_type_name(ty)))
|
.map(|ty| std::format!("_: {}", self.map_type_name(ty)))
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
#[cfg(feature = "metadata")]
|
#[cfg(feature = "metadata")]
|
||||||
@ -121,8 +119,8 @@ impl Engine {
|
|||||||
#[cfg(feature = "metadata")]
|
#[cfg(feature = "metadata")]
|
||||||
let param_type_names: crate::StaticVec<_> = F::param_names()
|
let param_type_names: crate::StaticVec<_> = F::param_names()
|
||||||
.iter()
|
.iter()
|
||||||
.map(|ty| crate::stdlib::format!("_: {}", self.map_type_name(ty)))
|
.map(|ty| std::format!("_: {}", self.map_type_name(ty)))
|
||||||
.chain(crate::stdlib::iter::once(
|
.chain(std::iter::once(
|
||||||
self.map_type_name(F::return_type_name()).into(),
|
self.map_type_name(F::return_type_name()).into(),
|
||||||
))
|
))
|
||||||
.collect();
|
.collect();
|
||||||
@ -905,7 +903,7 @@ impl Engine {
|
|||||||
module: Shared<Module>,
|
module: Shared<Module>,
|
||||||
) -> &mut Self {
|
) -> &mut Self {
|
||||||
fn register_static_module_raw(
|
fn register_static_module_raw(
|
||||||
root: &mut crate::stdlib::collections::BTreeMap<Identifier, Shared<Module>>,
|
root: &mut std::collections::BTreeMap<Identifier, Shared<Module>>,
|
||||||
name: impl AsRef<str> + Into<Identifier>,
|
name: impl AsRef<str> + Into<Identifier>,
|
||||||
module: Shared<Module>,
|
module: Shared<Module>,
|
||||||
) {
|
) {
|
||||||
@ -1039,8 +1037,8 @@ impl Engine {
|
|||||||
ast::{ASTNode, Expr, Stmt},
|
ast::{ASTNode, Expr, Stmt},
|
||||||
fn_native::shared_take_or_clone,
|
fn_native::shared_take_or_clone,
|
||||||
module::resolvers::StaticModuleResolver,
|
module::resolvers::StaticModuleResolver,
|
||||||
stdlib::collections::BTreeSet,
|
|
||||||
};
|
};
|
||||||
|
use std::collections::BTreeSet;
|
||||||
|
|
||||||
fn collect_imports(
|
fn collect_imports(
|
||||||
ast: &AST,
|
ast: &AST,
|
||||||
@ -1169,12 +1167,12 @@ impl Engine {
|
|||||||
/// Read the contents of a file into a string.
|
/// Read the contents of a file into a string.
|
||||||
#[cfg(not(feature = "no_std"))]
|
#[cfg(not(feature = "no_std"))]
|
||||||
#[cfg(not(any(target_arch = "wasm32", target_arch = "wasm64")))]
|
#[cfg(not(any(target_arch = "wasm32", target_arch = "wasm64")))]
|
||||||
fn read_file(path: crate::stdlib::path::PathBuf) -> Result<String, Box<EvalAltResult>> {
|
fn read_file(path: std::path::PathBuf) -> Result<String, Box<EvalAltResult>> {
|
||||||
use crate::stdlib::io::Read;
|
use std::io::Read;
|
||||||
|
|
||||||
let mut f = crate::stdlib::fs::File::open(path.clone()).map_err(|err| {
|
let mut f = std::fs::File::open(path.clone()).map_err(|err| {
|
||||||
EvalAltResult::ErrorSystem(
|
EvalAltResult::ErrorSystem(
|
||||||
crate::stdlib::format!("Cannot open script file '{}'", path.to_string_lossy()),
|
std::format!("Cannot open script file '{}'", path.to_string_lossy()),
|
||||||
err.into(),
|
err.into(),
|
||||||
)
|
)
|
||||||
})?;
|
})?;
|
||||||
@ -1183,7 +1181,7 @@ impl Engine {
|
|||||||
|
|
||||||
f.read_to_string(&mut contents).map_err(|err| {
|
f.read_to_string(&mut contents).map_err(|err| {
|
||||||
EvalAltResult::ErrorSystem(
|
EvalAltResult::ErrorSystem(
|
||||||
crate::stdlib::format!("Cannot read script file '{}'", path.to_string_lossy()),
|
std::format!("Cannot read script file '{}'", path.to_string_lossy()),
|
||||||
err.into(),
|
err.into(),
|
||||||
)
|
)
|
||||||
})?;
|
})?;
|
||||||
@ -1224,10 +1222,7 @@ impl Engine {
|
|||||||
#[cfg(not(feature = "no_std"))]
|
#[cfg(not(feature = "no_std"))]
|
||||||
#[cfg(not(any(target_arch = "wasm32", target_arch = "wasm64")))]
|
#[cfg(not(any(target_arch = "wasm32", target_arch = "wasm64")))]
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn compile_file(
|
pub fn compile_file(&self, path: std::path::PathBuf) -> Result<AST, Box<EvalAltResult>> {
|
||||||
&self,
|
|
||||||
path: crate::stdlib::path::PathBuf,
|
|
||||||
) -> Result<AST, Box<EvalAltResult>> {
|
|
||||||
self.compile_file_with_scope(&Default::default(), path)
|
self.compile_file_with_scope(&Default::default(), path)
|
||||||
}
|
}
|
||||||
/// Compile a script file into an [`AST`] using own scope, which can be used later for evaluation.
|
/// Compile a script file into an [`AST`] using own scope, which can be used later for evaluation.
|
||||||
@ -1269,7 +1264,7 @@ impl Engine {
|
|||||||
pub fn compile_file_with_scope(
|
pub fn compile_file_with_scope(
|
||||||
&self,
|
&self,
|
||||||
scope: &Scope,
|
scope: &Scope,
|
||||||
path: crate::stdlib::path::PathBuf,
|
path: std::path::PathBuf,
|
||||||
) -> Result<AST, Box<EvalAltResult>> {
|
) -> Result<AST, Box<EvalAltResult>> {
|
||||||
Self::read_file(path).and_then(|contents| Ok(self.compile_with_scope(scope, &contents)?))
|
Self::read_file(path).and_then(|contents| Ok(self.compile_with_scope(scope, &contents)?))
|
||||||
}
|
}
|
||||||
@ -1465,7 +1460,7 @@ impl Engine {
|
|||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn eval_file<T: Variant + Clone>(
|
pub fn eval_file<T: Variant + Clone>(
|
||||||
&self,
|
&self,
|
||||||
path: crate::stdlib::path::PathBuf,
|
path: std::path::PathBuf,
|
||||||
) -> Result<T, Box<EvalAltResult>> {
|
) -> Result<T, Box<EvalAltResult>> {
|
||||||
Self::read_file(path).and_then(|contents| self.eval::<T>(&contents))
|
Self::read_file(path).and_then(|contents| self.eval::<T>(&contents))
|
||||||
}
|
}
|
||||||
@ -1496,7 +1491,7 @@ impl Engine {
|
|||||||
pub fn eval_file_with_scope<T: Variant + Clone>(
|
pub fn eval_file_with_scope<T: Variant + Clone>(
|
||||||
&self,
|
&self,
|
||||||
scope: &mut Scope,
|
scope: &mut Scope,
|
||||||
path: crate::stdlib::path::PathBuf,
|
path: std::path::PathBuf,
|
||||||
) -> Result<T, Box<EvalAltResult>> {
|
) -> Result<T, Box<EvalAltResult>> {
|
||||||
Self::read_file(path).and_then(|contents| self.eval_with_scope::<T>(scope, &contents))
|
Self::read_file(path).and_then(|contents| self.eval_with_scope::<T>(scope, &contents))
|
||||||
}
|
}
|
||||||
@ -1711,10 +1706,7 @@ impl Engine {
|
|||||||
#[cfg(not(feature = "no_std"))]
|
#[cfg(not(feature = "no_std"))]
|
||||||
#[cfg(not(any(target_arch = "wasm32", target_arch = "wasm64")))]
|
#[cfg(not(any(target_arch = "wasm32", target_arch = "wasm64")))]
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn consume_file(
|
pub fn consume_file(&self, path: std::path::PathBuf) -> Result<(), Box<EvalAltResult>> {
|
||||||
&self,
|
|
||||||
path: crate::stdlib::path::PathBuf,
|
|
||||||
) -> Result<(), Box<EvalAltResult>> {
|
|
||||||
Self::read_file(path).and_then(|contents| self.consume(&contents))
|
Self::read_file(path).and_then(|contents| self.consume(&contents))
|
||||||
}
|
}
|
||||||
/// Evaluate a file with own scope, but throw away the result and only return error (if any).
|
/// Evaluate a file with own scope, but throw away the result and only return error (if any).
|
||||||
@ -1727,7 +1719,7 @@ impl Engine {
|
|||||||
pub fn consume_file_with_scope(
|
pub fn consume_file_with_scope(
|
||||||
&self,
|
&self,
|
||||||
scope: &mut Scope,
|
scope: &mut Scope,
|
||||||
path: crate::stdlib::path::PathBuf,
|
path: std::path::PathBuf,
|
||||||
) -> Result<(), Box<EvalAltResult>> {
|
) -> Result<(), Box<EvalAltResult>> {
|
||||||
Self::read_file(path).and_then(|contents| self.consume_with_scope(scope, &contents))
|
Self::read_file(path).and_then(|contents| self.consume_with_scope(scope, &contents))
|
||||||
}
|
}
|
||||||
@ -1787,12 +1779,10 @@ impl Engine {
|
|||||||
/// Call a script function defined in an [`AST`] with multiple arguments.
|
/// Call a script function defined in an [`AST`] with multiple arguments.
|
||||||
/// Arguments are passed as a tuple.
|
/// Arguments are passed as a tuple.
|
||||||
///
|
///
|
||||||
/// ## Warning
|
/// The [`AST`] is evaluated before calling the function.
|
||||||
///
|
/// This allows a script to load the necessary modules.
|
||||||
/// The [`AST`] is _not_ evaluated before calling the function. The function is called as-is.
|
/// This is usually desired. If not, a specialized [`AST`] can be prepared that contains only
|
||||||
///
|
/// function definitions without any body script via [`AST::clear_statements`].
|
||||||
/// If the [`AST`] needs to be evaluated before calling the function (usually to load external modules),
|
|
||||||
/// use [`call_fn_dynamic`][Engine::call_fn_dynamic].
|
|
||||||
///
|
///
|
||||||
/// # Example
|
/// # Example
|
||||||
///
|
///
|
||||||
@ -1838,9 +1828,9 @@ impl Engine {
|
|||||||
) -> Result<T, Box<EvalAltResult>> {
|
) -> Result<T, Box<EvalAltResult>> {
|
||||||
let mut arg_values: crate::StaticVec<_> = Default::default();
|
let mut arg_values: crate::StaticVec<_> = Default::default();
|
||||||
args.parse(&mut arg_values);
|
args.parse(&mut arg_values);
|
||||||
let mut args: crate::StaticVec<_> = arg_values.as_mut().iter_mut().collect();
|
let mut args: crate::StaticVec<_> = arg_values.iter_mut().collect();
|
||||||
|
|
||||||
let result = self.call_fn_dynamic_raw(scope, ast, false, name, &mut None, args.as_mut())?;
|
let result = self.call_fn_dynamic_raw(scope, ast, true, name, &mut None, &mut args)?;
|
||||||
|
|
||||||
let typ = self.map_type_name(result.type_name());
|
let typ = self.map_type_name(result.type_name());
|
||||||
|
|
||||||
@ -1856,8 +1846,7 @@ impl Engine {
|
|||||||
/// Call a script function defined in an [`AST`] with multiple [`Dynamic`] arguments
|
/// Call a script function defined in an [`AST`] with multiple [`Dynamic`] arguments
|
||||||
/// and optionally a value for binding to the `this` pointer.
|
/// and optionally a value for binding to the `this` pointer.
|
||||||
///
|
///
|
||||||
/// There is also an option to evaluate the [`AST`] (e.g. to configuration the environment)
|
/// There is an option to evaluate the [`AST`] to load necessary modules before calling the function.
|
||||||
/// before calling the function.
|
|
||||||
///
|
///
|
||||||
/// # WARNING
|
/// # WARNING
|
||||||
///
|
///
|
||||||
@ -1887,19 +1876,19 @@ impl Engine {
|
|||||||
/// scope.push("foo", 42_i64);
|
/// scope.push("foo", 42_i64);
|
||||||
///
|
///
|
||||||
/// // Call the script-defined function
|
/// // Call the script-defined function
|
||||||
/// let result = engine.call_fn_dynamic(&mut scope, &ast, false, "add", None, [ "abc".into(), 123_i64.into() ])?;
|
/// let result = engine.call_fn_dynamic(&mut scope, &ast, true, "add", None, [ "abc".into(), 123_i64.into() ])?;
|
||||||
/// // ^^^^ no 'this' pointer
|
/// // ^^^^ no 'this' pointer
|
||||||
/// assert_eq!(result.cast::<i64>(), 168);
|
/// assert_eq!(result.cast::<i64>(), 168);
|
||||||
///
|
///
|
||||||
/// let result = engine.call_fn_dynamic(&mut scope, &ast, false, "add1", None, [ "abc".into() ])?;
|
/// let result = engine.call_fn_dynamic(&mut scope, &ast, true, "add1", None, [ "abc".into() ])?;
|
||||||
/// assert_eq!(result.cast::<i64>(), 46);
|
/// assert_eq!(result.cast::<i64>(), 46);
|
||||||
///
|
///
|
||||||
/// let result = engine.call_fn_dynamic(&mut scope, &ast, false, "bar", None, [])?;
|
/// let result = engine.call_fn_dynamic(&mut scope, &ast, true, "bar", None, [])?;
|
||||||
/// assert_eq!(result.cast::<i64>(), 21);
|
/// assert_eq!(result.cast::<i64>(), 21);
|
||||||
///
|
///
|
||||||
/// let mut value: Dynamic = 1_i64.into();
|
/// let mut value: Dynamic = 1_i64.into();
|
||||||
/// let result = engine.call_fn_dynamic(&mut scope, &ast, false, "action", Some(&mut value), [ 41_i64.into() ])?;
|
/// let result = engine.call_fn_dynamic(&mut scope, &ast, true, "action", Some(&mut value), [ 41_i64.into() ])?;
|
||||||
/// // ^^^^^^^^^^^^^^^^ binding the 'this' pointer
|
/// // ^^^^^^^^^^^^^^^^ binding the 'this' pointer
|
||||||
/// assert_eq!(value.as_int().unwrap(), 42);
|
/// assert_eq!(value.as_int().unwrap(), 42);
|
||||||
/// # }
|
/// # }
|
||||||
/// # Ok(())
|
/// # Ok(())
|
||||||
@ -1918,7 +1907,7 @@ impl Engine {
|
|||||||
) -> RhaiResult {
|
) -> RhaiResult {
|
||||||
let mut args: crate::StaticVec<_> = arg_values.as_mut().iter_mut().collect();
|
let mut args: crate::StaticVec<_> = arg_values.as_mut().iter_mut().collect();
|
||||||
|
|
||||||
self.call_fn_dynamic_raw(scope, ast, eval_ast, name, &mut this_ptr, args.as_mut())
|
self.call_fn_dynamic_raw(scope, ast, eval_ast, name, &mut this_ptr, &mut args)
|
||||||
}
|
}
|
||||||
/// Call a script function defined in an [`AST`] with multiple [`Dynamic`] arguments.
|
/// Call a script function defined in an [`AST`] with multiple [`Dynamic`] arguments.
|
||||||
///
|
///
|
||||||
@ -2002,7 +1991,7 @@ impl Engine {
|
|||||||
#[cfg(feature = "no_function")]
|
#[cfg(feature = "no_function")]
|
||||||
let lib = Default::default();
|
let lib = Default::default();
|
||||||
|
|
||||||
let stmt = crate::stdlib::mem::take(ast.statements_mut());
|
let stmt = std::mem::take(ast.statements_mut());
|
||||||
crate::optimize::optimize_into_ast(self, scope, stmt.into_vec(), lib, optimization_level)
|
crate::optimize::optimize_into_ast(self, scope, stmt.into_vec(), lib, optimization_level)
|
||||||
}
|
}
|
||||||
/// Generate a list of all registered functions.
|
/// Generate a list of all registered functions.
|
||||||
@ -2013,15 +2002,15 @@ impl Engine {
|
|||||||
/// 2) Functions in registered sub-modules
|
/// 2) Functions in registered sub-modules
|
||||||
/// 3) Functions in packages (optional)
|
/// 3) Functions in packages (optional)
|
||||||
#[cfg(feature = "metadata")]
|
#[cfg(feature = "metadata")]
|
||||||
pub fn gen_fn_signatures(&self, include_packages: bool) -> crate::stdlib::vec::Vec<String> {
|
pub fn gen_fn_signatures(&self, include_packages: bool) -> std::vec::Vec<String> {
|
||||||
let mut signatures: crate::stdlib::vec::Vec<_> = Default::default();
|
let mut signatures: std::vec::Vec<_> = Default::default();
|
||||||
|
|
||||||
signatures.extend(self.global_namespace.gen_fn_signatures());
|
signatures.extend(self.global_namespace.gen_fn_signatures());
|
||||||
|
|
||||||
self.global_sub_modules.iter().for_each(|(name, m)| {
|
self.global_sub_modules.iter().for_each(|(name, m)| {
|
||||||
signatures.extend(
|
signatures.extend(
|
||||||
m.gen_fn_signatures()
|
m.gen_fn_signatures()
|
||||||
.map(|f| crate::stdlib::format!("{}::{}", name, f)),
|
.map(|f| std::format!("{}::{}", name, f)),
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1,15 +1,13 @@
|
|||||||
//! Configuration settings for [`Engine`].
|
//! Configuration settings for [`Engine`].
|
||||||
|
|
||||||
use crate::stdlib::{format, string::String};
|
|
||||||
use crate::token::Token;
|
use crate::token::Token;
|
||||||
use crate::Engine;
|
use crate::Engine;
|
||||||
use crate::{engine::Precedence, Identifier};
|
use crate::{engine::Precedence, Identifier};
|
||||||
|
#[cfg(feature = "no_std")]
|
||||||
|
use std::prelude::v1::*;
|
||||||
|
|
||||||
#[cfg(not(feature = "unchecked"))]
|
#[cfg(not(feature = "unchecked"))]
|
||||||
use crate::stdlib::num::{NonZeroU64, NonZeroUsize};
|
use std::num::{NonZeroU64, NonZeroUsize};
|
||||||
|
|
||||||
#[cfg(not(feature = "no_module"))]
|
|
||||||
use crate::stdlib::boxed::Box;
|
|
||||||
|
|
||||||
impl Engine {
|
impl Engine {
|
||||||
/// Control whether and how the [`Engine`] will optimize an [`AST`][crate::AST] after compilation.
|
/// Control whether and how the [`Engine`] will optimize an [`AST`][crate::AST] after compilation.
|
||||||
|
@ -4,8 +4,8 @@
|
|||||||
#![allow(non_snake_case)]
|
#![allow(non_snake_case)]
|
||||||
|
|
||||||
use crate::dynamic::Variant;
|
use crate::dynamic::Variant;
|
||||||
use crate::stdlib::vec::Vec;
|
|
||||||
use crate::{Dynamic, StaticVec};
|
use crate::{Dynamic, StaticVec};
|
||||||
|
use std::vec::Vec;
|
||||||
|
|
||||||
/// Trait that parses arguments to a function call.
|
/// Trait that parses arguments to a function call.
|
||||||
///
|
///
|
||||||
|
@ -2,8 +2,10 @@
|
|||||||
|
|
||||||
use crate::engine::OP_CONTAINS;
|
use crate::engine::OP_CONTAINS;
|
||||||
use crate::fn_native::{FnCallArgs, NativeCallContext};
|
use crate::fn_native::{FnCallArgs, NativeCallContext};
|
||||||
use crate::stdlib::{any::TypeId, format, string::ToString};
|
|
||||||
use crate::{Dynamic, ImmutableString, RhaiResult, INT};
|
use crate::{Dynamic, ImmutableString, RhaiResult, INT};
|
||||||
|
use std::any::TypeId;
|
||||||
|
#[cfg(feature = "no_std")]
|
||||||
|
use std::prelude::v1::*;
|
||||||
|
|
||||||
#[cfg(not(feature = "no_float"))]
|
#[cfg(not(feature = "no_float"))]
|
||||||
use crate::FLOAT;
|
use crate::FLOAT;
|
||||||
|
@ -10,16 +10,6 @@ use crate::fn_builtin::{get_builtin_binary_op_fn, get_builtin_op_assignment_fn};
|
|||||||
use crate::fn_native::{FnAny, FnCallArgs};
|
use crate::fn_native::{FnAny, FnCallArgs};
|
||||||
use crate::module::NamespaceRef;
|
use crate::module::NamespaceRef;
|
||||||
use crate::optimize::OptimizationLevel;
|
use crate::optimize::OptimizationLevel;
|
||||||
use crate::stdlib::{
|
|
||||||
any::{type_name, TypeId},
|
|
||||||
boxed::Box,
|
|
||||||
convert::TryFrom,
|
|
||||||
format,
|
|
||||||
iter::{empty, once},
|
|
||||||
mem,
|
|
||||||
string::{String, ToString},
|
|
||||||
vec::Vec,
|
|
||||||
};
|
|
||||||
use crate::{
|
use crate::{
|
||||||
ast::{Expr, Stmt},
|
ast::{Expr, Stmt},
|
||||||
fn_native::CallableFunction,
|
fn_native::CallableFunction,
|
||||||
@ -29,6 +19,14 @@ use crate::{
|
|||||||
calc_fn_hash, calc_fn_params_hash, combine_hashes, Dynamic, Engine, EvalAltResult, FnPtr,
|
calc_fn_hash, calc_fn_params_hash, combine_hashes, Dynamic, Engine, EvalAltResult, FnPtr,
|
||||||
ImmutableString, Module, ParseErrorType, Position, Scope, StaticVec,
|
ImmutableString, Module, ParseErrorType, Position, Scope, StaticVec,
|
||||||
};
|
};
|
||||||
|
#[cfg(feature = "no_std")]
|
||||||
|
use std::prelude::v1::*;
|
||||||
|
use std::{
|
||||||
|
any::{type_name, TypeId},
|
||||||
|
convert::TryFrom,
|
||||||
|
iter::{empty, once},
|
||||||
|
mem,
|
||||||
|
};
|
||||||
|
|
||||||
#[cfg(not(feature = "no_object"))]
|
#[cfg(not(feature = "no_object"))]
|
||||||
use crate::Map;
|
use crate::Map;
|
||||||
@ -465,7 +463,7 @@ impl Engine {
|
|||||||
) -> RhaiResult {
|
) -> RhaiResult {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn make_error(
|
fn make_error(
|
||||||
name: crate::stdlib::string::String,
|
name: std::string::String,
|
||||||
fn_def: &crate::ast::ScriptFnDef,
|
fn_def: &crate::ast::ScriptFnDef,
|
||||||
state: &State,
|
state: &State,
|
||||||
err: Box<EvalAltResult>,
|
err: Box<EvalAltResult>,
|
||||||
@ -512,7 +510,7 @@ impl Engine {
|
|||||||
.iter()
|
.iter()
|
||||||
.zip(args.iter_mut().map(|v| mem::take(*v)))
|
.zip(args.iter_mut().map(|v| mem::take(*v)))
|
||||||
.map(|(name, value)| {
|
.map(|(name, value)| {
|
||||||
let var_name: crate::stdlib::borrow::Cow<'_, str> =
|
let var_name: std::borrow::Cow<'_, str> =
|
||||||
crate::r#unsafe::unsafe_cast_var_name_to_lifetime(name).into();
|
crate::r#unsafe::unsafe_cast_var_name_to_lifetime(name).into();
|
||||||
(var_name, value)
|
(var_name, value)
|
||||||
}),
|
}),
|
||||||
@ -913,15 +911,14 @@ impl Engine {
|
|||||||
let new_hash = FnCallHash::from_script(calc_fn_hash(empty(), fn_name, args_len));
|
let new_hash = FnCallHash::from_script(calc_fn_hash(empty(), fn_name, args_len));
|
||||||
// Arguments are passed as-is, adding the curried arguments
|
// Arguments are passed as-is, adding the curried arguments
|
||||||
let mut curry = fn_ptr.curry().iter().cloned().collect::<StaticVec<_>>();
|
let mut curry = fn_ptr.curry().iter().cloned().collect::<StaticVec<_>>();
|
||||||
let mut arg_values = curry
|
let mut args = curry
|
||||||
.iter_mut()
|
.iter_mut()
|
||||||
.chain(call_args.iter_mut())
|
.chain(call_args.iter_mut())
|
||||||
.collect::<StaticVec<_>>();
|
.collect::<StaticVec<_>>();
|
||||||
let args = arg_values.as_mut();
|
|
||||||
|
|
||||||
// Map it to name(args) in function-call style
|
// Map it to name(args) in function-call style
|
||||||
self.exec_fn_call(
|
self.exec_fn_call(
|
||||||
mods, state, lib, fn_name, new_hash, args, false, false, pos, None, level,
|
mods, state, lib, fn_name, new_hash, &mut args, false, false, pos, None, level,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
KEYWORD_FN_PTR_CALL => {
|
KEYWORD_FN_PTR_CALL => {
|
||||||
@ -952,15 +949,14 @@ impl Engine {
|
|||||||
);
|
);
|
||||||
// Replace the first argument with the object pointer, adding the curried arguments
|
// Replace the first argument with the object pointer, adding the curried arguments
|
||||||
let mut curry = fn_ptr.curry().iter().cloned().collect::<StaticVec<_>>();
|
let mut curry = fn_ptr.curry().iter().cloned().collect::<StaticVec<_>>();
|
||||||
let mut arg_values = once(obj)
|
let mut args = once(obj)
|
||||||
.chain(curry.iter_mut())
|
.chain(curry.iter_mut())
|
||||||
.chain(call_args.iter_mut())
|
.chain(call_args.iter_mut())
|
||||||
.collect::<StaticVec<_>>();
|
.collect::<StaticVec<_>>();
|
||||||
let args = arg_values.as_mut();
|
|
||||||
|
|
||||||
// Map it to name(args) in function-call style
|
// Map it to name(args) in function-call style
|
||||||
self.exec_fn_call(
|
self.exec_fn_call(
|
||||||
mods, state, lib, fn_name, new_hash, args, is_ref, true, pos, None, level,
|
mods, state, lib, fn_name, new_hash, &mut args, is_ref, true, pos, None, level,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
KEYWORD_FN_PTR_CURRY => {
|
KEYWORD_FN_PTR_CURRY => {
|
||||||
@ -1030,13 +1026,12 @@ impl Engine {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Attached object pointer in front of the arguments
|
// Attached object pointer in front of the arguments
|
||||||
let mut arg_values = once(obj)
|
let mut args = once(obj)
|
||||||
.chain(call_args.iter_mut())
|
.chain(call_args.iter_mut())
|
||||||
.collect::<StaticVec<_>>();
|
.collect::<StaticVec<_>>();
|
||||||
let args = arg_values.as_mut();
|
|
||||||
|
|
||||||
self.exec_fn_call(
|
self.exec_fn_call(
|
||||||
mods, state, lib, fn_name, hash, args, is_ref, true, pos, None, level,
|
mods, state, lib, fn_name, hash, &mut args, is_ref, true, pos, None, level,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}?;
|
}?;
|
||||||
@ -1314,7 +1309,12 @@ impl Engine {
|
|||||||
|
|
||||||
self.inc_operations(state, pos)?;
|
self.inc_operations(state, pos)?;
|
||||||
|
|
||||||
args = if target.is_shared() || target.is_value() {
|
#[cfg(not(feature = "no_closure"))]
|
||||||
|
let target_is_shared = target.is_shared();
|
||||||
|
#[cfg(feature = "no_closure")]
|
||||||
|
let target_is_shared = false;
|
||||||
|
|
||||||
|
args = if target_is_shared || target.is_value() {
|
||||||
arg_values.insert(0, target.take_or_clone().flatten());
|
arg_values.insert(0, target.take_or_clone().flatten());
|
||||||
arg_values.iter_mut().collect()
|
arg_values.iter_mut().collect()
|
||||||
} else {
|
} else {
|
||||||
@ -1339,10 +1339,8 @@ impl Engine {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let args = args.as_mut();
|
|
||||||
|
|
||||||
self.exec_fn_call(
|
self.exec_fn_call(
|
||||||
mods, state, lib, name, hash, args, is_ref, false, pos, capture, level,
|
mods, state, lib, name, hash, &mut args, is_ref, false, pos, capture, level,
|
||||||
)
|
)
|
||||||
.map(|(v, _)| v)
|
.map(|(v, _)| v)
|
||||||
}
|
}
|
||||||
@ -1398,7 +1396,12 @@ impl Engine {
|
|||||||
|
|
||||||
self.inc_operations(state, pos)?;
|
self.inc_operations(state, pos)?;
|
||||||
|
|
||||||
if target.is_shared() || target.is_value() {
|
#[cfg(not(feature = "no_closure"))]
|
||||||
|
let target_is_shared = target.is_shared();
|
||||||
|
#[cfg(feature = "no_closure")]
|
||||||
|
let target_is_shared = false;
|
||||||
|
|
||||||
|
if target_is_shared || target.is_value() {
|
||||||
arg_values[0] = target.take_or_clone().flatten();
|
arg_values[0] = target.take_or_clone().flatten();
|
||||||
args = arg_values.iter_mut().collect();
|
args = arg_values.iter_mut().collect();
|
||||||
} else {
|
} else {
|
||||||
@ -1458,7 +1461,6 @@ impl Engine {
|
|||||||
if fn_def.body.is_empty() {
|
if fn_def.body.is_empty() {
|
||||||
Ok(Dynamic::UNIT)
|
Ok(Dynamic::UNIT)
|
||||||
} else {
|
} else {
|
||||||
let args = args.as_mut();
|
|
||||||
let new_scope = &mut Default::default();
|
let new_scope = &mut Default::default();
|
||||||
|
|
||||||
let mut source = module.id_raw().cloned();
|
let mut source = module.id_raw().cloned();
|
||||||
@ -1467,7 +1469,7 @@ impl Engine {
|
|||||||
let level = level + 1;
|
let level = level + 1;
|
||||||
|
|
||||||
let result = self.call_script_fn(
|
let result = self.call_script_fn(
|
||||||
new_scope, mods, state, lib, &mut None, fn_def, args, pos, level,
|
new_scope, mods, state, lib, &mut None, fn_def, &mut args, pos, level,
|
||||||
);
|
);
|
||||||
|
|
||||||
state.source = source;
|
state.source = source;
|
||||||
@ -1479,17 +1481,13 @@ impl Engine {
|
|||||||
Some(f) if f.is_plugin_fn() => f
|
Some(f) if f.is_plugin_fn() => f
|
||||||
.get_plugin_fn()
|
.get_plugin_fn()
|
||||||
.clone()
|
.clone()
|
||||||
.call(
|
.call((self, fn_name, module.id(), &*mods, lib).into(), &mut args)
|
||||||
(self, fn_name, module.id(), &*mods, lib).into(),
|
|
||||||
args.as_mut(),
|
|
||||||
)
|
|
||||||
.map_err(|err| err.fill_position(pos)),
|
.map_err(|err| err.fill_position(pos)),
|
||||||
|
|
||||||
Some(f) if f.is_native() => f.get_native_fn()(
|
Some(f) if f.is_native() => {
|
||||||
(self, fn_name, module.id(), &*mods, lib).into(),
|
f.get_native_fn()((self, fn_name, module.id(), &*mods, lib).into(), &mut args)
|
||||||
args.as_mut(),
|
.map_err(|err| err.fill_position(pos))
|
||||||
)
|
}
|
||||||
.map_err(|err| err.fill_position(pos)),
|
|
||||||
|
|
||||||
Some(f) => unreachable!("unknown function type: {:?}", f),
|
Some(f) => unreachable!("unknown function type: {:?}", f),
|
||||||
|
|
||||||
|
@ -4,8 +4,9 @@
|
|||||||
#![allow(non_snake_case)]
|
#![allow(non_snake_case)]
|
||||||
|
|
||||||
use crate::dynamic::Variant;
|
use crate::dynamic::Variant;
|
||||||
use crate::stdlib::{boxed::Box, string::ToString};
|
|
||||||
use crate::{Engine, EvalAltResult, ParseError, Scope, AST};
|
use crate::{Engine, EvalAltResult, ParseError, Scope, AST};
|
||||||
|
#[cfg(feature = "no_std")]
|
||||||
|
use std::prelude::v1::*;
|
||||||
|
|
||||||
/// Trait to create a Rust closure from a script.
|
/// Trait to create a Rust closure from a script.
|
||||||
///
|
///
|
||||||
|
@ -3,19 +3,19 @@
|
|||||||
use crate::ast::{FnAccess, FnCallHash};
|
use crate::ast::{FnAccess, FnCallHash};
|
||||||
use crate::engine::Imports;
|
use crate::engine::Imports;
|
||||||
use crate::plugin::PluginFunction;
|
use crate::plugin::PluginFunction;
|
||||||
use crate::stdlib::{
|
|
||||||
boxed::Box,
|
|
||||||
convert::{TryFrom, TryInto},
|
|
||||||
fmt,
|
|
||||||
iter::{empty, once},
|
|
||||||
mem,
|
|
||||||
string::String,
|
|
||||||
};
|
|
||||||
use crate::token::is_valid_identifier;
|
use crate::token::is_valid_identifier;
|
||||||
use crate::{
|
use crate::{
|
||||||
calc_fn_hash, Dynamic, Engine, EvalAltResult, EvalContext, Identifier, ImmutableString, Module,
|
calc_fn_hash, Dynamic, Engine, EvalAltResult, EvalContext, Identifier, ImmutableString, Module,
|
||||||
Position, RhaiResult, StaticVec,
|
Position, RhaiResult, StaticVec,
|
||||||
};
|
};
|
||||||
|
#[cfg(feature = "no_std")]
|
||||||
|
use std::prelude::v1::*;
|
||||||
|
use std::{
|
||||||
|
convert::{TryFrom, TryInto},
|
||||||
|
fmt,
|
||||||
|
iter::{empty, once},
|
||||||
|
mem,
|
||||||
|
};
|
||||||
|
|
||||||
/// Trait that maps to `Send + Sync` only under the `sync` feature.
|
/// Trait that maps to `Send + Sync` only under the `sync` feature.
|
||||||
#[cfg(feature = "sync")]
|
#[cfg(feature = "sync")]
|
||||||
@ -33,19 +33,19 @@ impl<T> SendSync for T {}
|
|||||||
|
|
||||||
/// Immutable reference-counted container.
|
/// Immutable reference-counted container.
|
||||||
#[cfg(not(feature = "sync"))]
|
#[cfg(not(feature = "sync"))]
|
||||||
pub use crate::stdlib::rc::Rc as Shared;
|
pub use std::rc::Rc as Shared;
|
||||||
/// Immutable reference-counted container.
|
/// Immutable reference-counted container.
|
||||||
#[cfg(feature = "sync")]
|
#[cfg(feature = "sync")]
|
||||||
pub use crate::stdlib::sync::Arc as Shared;
|
pub use std::sync::Arc as Shared;
|
||||||
|
|
||||||
/// Synchronized shared object.
|
/// Synchronized shared object.
|
||||||
#[cfg(not(feature = "no_closure"))]
|
#[cfg(not(feature = "no_closure"))]
|
||||||
#[cfg(not(feature = "sync"))]
|
#[cfg(not(feature = "sync"))]
|
||||||
pub use crate::stdlib::cell::RefCell as Locked;
|
pub use std::cell::RefCell as Locked;
|
||||||
/// Synchronized shared object.
|
/// Synchronized shared object.
|
||||||
#[cfg(not(feature = "no_closure"))]
|
#[cfg(not(feature = "no_closure"))]
|
||||||
#[cfg(feature = "sync")]
|
#[cfg(feature = "sync")]
|
||||||
pub use crate::stdlib::sync::RwLock as Locked;
|
pub use std::sync::RwLock as Locked;
|
||||||
|
|
||||||
/// Context of a native Rust function call.
|
/// Context of a native Rust function call.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@ -348,7 +348,7 @@ impl FnPtr {
|
|||||||
arg_values.iter_mut().collect()
|
arg_values.iter_mut().collect()
|
||||||
};
|
};
|
||||||
|
|
||||||
ctx.call_fn_dynamic_raw(self.fn_name(), is_method, args.as_mut())
|
ctx.call_fn_dynamic_raw(self.fn_name(), is_method, &mut args)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,8 +5,10 @@
|
|||||||
use crate::dynamic::{DynamicWriteLock, Variant};
|
use crate::dynamic::{DynamicWriteLock, Variant};
|
||||||
use crate::fn_native::{CallableFunction, FnAny, FnCallArgs, SendSync};
|
use crate::fn_native::{CallableFunction, FnAny, FnCallArgs, SendSync};
|
||||||
use crate::r#unsafe::unsafe_try_cast;
|
use crate::r#unsafe::unsafe_try_cast;
|
||||||
use crate::stdlib::{any::TypeId, boxed::Box, mem, string::String, vec};
|
|
||||||
use crate::{Dynamic, EvalAltResult, NativeCallContext};
|
use crate::{Dynamic, EvalAltResult, NativeCallContext};
|
||||||
|
#[cfg(feature = "no_std")]
|
||||||
|
use std::prelude::v1::*;
|
||||||
|
use std::{any::TypeId, mem};
|
||||||
|
|
||||||
// These types are used to build a unique _marker_ tuple type for each combination
|
// These types are used to build a unique _marker_ tuple type for each combination
|
||||||
// of function parameter types in order to make each trait implementation unique.
|
// of function parameter types in order to make each trait implementation unique.
|
||||||
@ -91,9 +93,9 @@ macro_rules! def_register {
|
|||||||
RET: Variant + Clone
|
RET: Variant + Clone
|
||||||
> RegisterNativeFunction<($($mark,)*), ()> for FN {
|
> RegisterNativeFunction<($($mark,)*), ()> for FN {
|
||||||
#[inline(always)] fn param_types() -> Box<[TypeId]> { vec![$(TypeId::of::<$par>()),*].into_boxed_slice() }
|
#[inline(always)] fn param_types() -> Box<[TypeId]> { vec![$(TypeId::of::<$par>()),*].into_boxed_slice() }
|
||||||
#[cfg(feature = "metadata")] #[inline(always)] fn param_names() -> Box<[&'static str]> { vec![$(crate::stdlib::any::type_name::<$par>()),*].into_boxed_slice() }
|
#[cfg(feature = "metadata")] #[inline(always)] fn param_names() -> Box<[&'static str]> { vec![$(std::any::type_name::<$par>()),*].into_boxed_slice() }
|
||||||
#[cfg(feature = "metadata")] #[inline(always)] fn return_type() -> TypeId { TypeId::of::<RET>() }
|
#[cfg(feature = "metadata")] #[inline(always)] fn return_type() -> TypeId { TypeId::of::<RET>() }
|
||||||
#[cfg(feature = "metadata")] #[inline(always)] fn return_type_name() -> &'static str { crate::stdlib::any::type_name::<RET>() }
|
#[cfg(feature = "metadata")] #[inline(always)] fn return_type_name() -> &'static str { std::any::type_name::<RET>() }
|
||||||
#[inline(always)] fn into_callable_function(self) -> CallableFunction {
|
#[inline(always)] fn into_callable_function(self) -> CallableFunction {
|
||||||
CallableFunction::$abi(Box::new(move |_: NativeCallContext, args: &mut FnCallArgs| {
|
CallableFunction::$abi(Box::new(move |_: NativeCallContext, args: &mut FnCallArgs| {
|
||||||
// The arguments are assumed to be of the correct number and types!
|
// The arguments are assumed to be of the correct number and types!
|
||||||
@ -115,9 +117,9 @@ macro_rules! def_register {
|
|||||||
RET: Variant + Clone
|
RET: Variant + Clone
|
||||||
> RegisterNativeFunction<(NativeCallContext<'static>, $($mark,)*), ()> for FN {
|
> RegisterNativeFunction<(NativeCallContext<'static>, $($mark,)*), ()> for FN {
|
||||||
#[inline(always)] fn param_types() -> Box<[TypeId]> { vec![$(TypeId::of::<$par>()),*].into_boxed_slice() }
|
#[inline(always)] fn param_types() -> Box<[TypeId]> { vec![$(TypeId::of::<$par>()),*].into_boxed_slice() }
|
||||||
#[cfg(feature = "metadata")] #[inline(always)] fn param_names() -> Box<[&'static str]> { vec![$(crate::stdlib::any::type_name::<$par>()),*].into_boxed_slice() }
|
#[cfg(feature = "metadata")] #[inline(always)] fn param_names() -> Box<[&'static str]> { vec![$(std::any::type_name::<$par>()),*].into_boxed_slice() }
|
||||||
#[cfg(feature = "metadata")] #[inline(always)] fn return_type() -> TypeId { TypeId::of::<RET>() }
|
#[cfg(feature = "metadata")] #[inline(always)] fn return_type() -> TypeId { TypeId::of::<RET>() }
|
||||||
#[cfg(feature = "metadata")] #[inline(always)] fn return_type_name() -> &'static str { crate::stdlib::any::type_name::<RET>() }
|
#[cfg(feature = "metadata")] #[inline(always)] fn return_type_name() -> &'static str { std::any::type_name::<RET>() }
|
||||||
#[inline(always)] fn into_callable_function(self) -> CallableFunction {
|
#[inline(always)] fn into_callable_function(self) -> CallableFunction {
|
||||||
CallableFunction::$abi(Box::new(move |ctx: NativeCallContext, args: &mut FnCallArgs| {
|
CallableFunction::$abi(Box::new(move |ctx: NativeCallContext, args: &mut FnCallArgs| {
|
||||||
// The arguments are assumed to be of the correct number and types!
|
// The arguments are assumed to be of the correct number and types!
|
||||||
@ -139,9 +141,9 @@ macro_rules! def_register {
|
|||||||
RET: Variant + Clone
|
RET: Variant + Clone
|
||||||
> RegisterNativeFunction<($($mark,)*), Result<RET, Box<EvalAltResult>>> for FN {
|
> RegisterNativeFunction<($($mark,)*), Result<RET, Box<EvalAltResult>>> for FN {
|
||||||
#[inline(always)] fn param_types() -> Box<[TypeId]> { vec![$(TypeId::of::<$par>()),*].into_boxed_slice() }
|
#[inline(always)] fn param_types() -> Box<[TypeId]> { vec![$(TypeId::of::<$par>()),*].into_boxed_slice() }
|
||||||
#[cfg(feature = "metadata")] #[inline(always)] fn param_names() -> Box<[&'static str]> { vec![$(crate::stdlib::any::type_name::<$par>()),*].into_boxed_slice() }
|
#[cfg(feature = "metadata")] #[inline(always)] fn param_names() -> Box<[&'static str]> { vec![$(std::any::type_name::<$par>()),*].into_boxed_slice() }
|
||||||
#[cfg(feature = "metadata")] #[inline(always)] fn return_type() -> TypeId { TypeId::of::<Result<RET, Box<EvalAltResult>>>() }
|
#[cfg(feature = "metadata")] #[inline(always)] fn return_type() -> TypeId { TypeId::of::<Result<RET, Box<EvalAltResult>>>() }
|
||||||
#[cfg(feature = "metadata")] #[inline(always)] fn return_type_name() -> &'static str { crate::stdlib::any::type_name::<Result<RET, Box<EvalAltResult>>>() }
|
#[cfg(feature = "metadata")] #[inline(always)] fn return_type_name() -> &'static str { std::any::type_name::<Result<RET, Box<EvalAltResult>>>() }
|
||||||
#[inline(always)] fn into_callable_function(self) -> CallableFunction {
|
#[inline(always)] fn into_callable_function(self) -> CallableFunction {
|
||||||
CallableFunction::$abi(Box::new(move |_: NativeCallContext, args: &mut FnCallArgs| {
|
CallableFunction::$abi(Box::new(move |_: NativeCallContext, args: &mut FnCallArgs| {
|
||||||
// The arguments are assumed to be of the correct number and types!
|
// The arguments are assumed to be of the correct number and types!
|
||||||
@ -160,9 +162,9 @@ macro_rules! def_register {
|
|||||||
RET: Variant + Clone
|
RET: Variant + Clone
|
||||||
> RegisterNativeFunction<(NativeCallContext<'static>, $($mark,)*), Result<RET, Box<EvalAltResult>>> for FN {
|
> RegisterNativeFunction<(NativeCallContext<'static>, $($mark,)*), Result<RET, Box<EvalAltResult>>> for FN {
|
||||||
#[inline(always)] fn param_types() -> Box<[TypeId]> { vec![$(TypeId::of::<$par>()),*].into_boxed_slice() }
|
#[inline(always)] fn param_types() -> Box<[TypeId]> { vec![$(TypeId::of::<$par>()),*].into_boxed_slice() }
|
||||||
#[cfg(feature = "metadata")] #[inline(always)] fn param_names() -> Box<[&'static str]> { vec![$(crate::stdlib::any::type_name::<$par>()),*].into_boxed_slice() }
|
#[cfg(feature = "metadata")] #[inline(always)] fn param_names() -> Box<[&'static str]> { vec![$(std::any::type_name::<$par>()),*].into_boxed_slice() }
|
||||||
#[cfg(feature = "metadata")] #[inline(always)] fn return_type() -> TypeId { TypeId::of::<Result<RET, Box<EvalAltResult>>>() }
|
#[cfg(feature = "metadata")] #[inline(always)] fn return_type() -> TypeId { TypeId::of::<Result<RET, Box<EvalAltResult>>>() }
|
||||||
#[cfg(feature = "metadata")] #[inline(always)] fn return_type_name() -> &'static str { crate::stdlib::any::type_name::<Result<RET, Box<EvalAltResult>>>() }
|
#[cfg(feature = "metadata")] #[inline(always)] fn return_type_name() -> &'static str { std::any::type_name::<Result<RET, Box<EvalAltResult>>>() }
|
||||||
#[inline(always)] fn into_callable_function(self) -> CallableFunction {
|
#[inline(always)] fn into_callable_function(self) -> CallableFunction {
|
||||||
CallableFunction::$abi(Box::new(move |ctx: NativeCallContext, args: &mut FnCallArgs| {
|
CallableFunction::$abi(Box::new(move |ctx: NativeCallContext, args: &mut FnCallArgs| {
|
||||||
// The arguments are assumed to be of the correct number and types!
|
// The arguments are assumed to be of the correct number and types!
|
||||||
|
21
src/lib.rs
21
src/lib.rs
@ -61,6 +61,12 @@
|
|||||||
#[cfg(feature = "no_std")]
|
#[cfg(feature = "no_std")]
|
||||||
extern crate alloc;
|
extern crate alloc;
|
||||||
|
|
||||||
|
#[cfg(feature = "no_std")]
|
||||||
|
extern crate no_std_compat as std;
|
||||||
|
|
||||||
|
#[cfg(feature = "no_std")]
|
||||||
|
use std::prelude::v1::*;
|
||||||
|
|
||||||
// Internal modules
|
// Internal modules
|
||||||
|
|
||||||
mod ast;
|
mod ast;
|
||||||
@ -82,13 +88,12 @@ mod parser;
|
|||||||
pub mod plugin;
|
pub mod plugin;
|
||||||
mod result;
|
mod result;
|
||||||
mod scope;
|
mod scope;
|
||||||
mod stdlib;
|
|
||||||
mod syntax;
|
mod syntax;
|
||||||
mod token;
|
mod token;
|
||||||
mod r#unsafe;
|
mod r#unsafe;
|
||||||
mod utils;
|
mod utils;
|
||||||
|
|
||||||
type RhaiResult = stdlib::result::Result<Dynamic, stdlib::boxed::Box<EvalAltResult>>;
|
type RhaiResult = Result<Dynamic, Box<EvalAltResult>>;
|
||||||
|
|
||||||
/// The system integer type. It is defined as [`i64`].
|
/// The system integer type. It is defined as [`i64`].
|
||||||
///
|
///
|
||||||
@ -104,20 +109,18 @@ pub type INT = i64;
|
|||||||
pub type INT = i32;
|
pub type INT = i32;
|
||||||
|
|
||||||
/// The system floating-point type. It is defined as [`f64`].
|
/// The system floating-point type. It is defined as [`f64`].
|
||||||
|
/// Not available under `no_float`.
|
||||||
///
|
///
|
||||||
/// If the `f32_float` feature is enabled, this will be [`i32`] instead.
|
/// If the `f32_float` feature is enabled, this will be [`i32`] instead.
|
||||||
///
|
|
||||||
/// Not available under `no_float`.
|
|
||||||
#[cfg(not(feature = "no_float"))]
|
#[cfg(not(feature = "no_float"))]
|
||||||
#[cfg(not(feature = "f32_float"))]
|
#[cfg(not(feature = "f32_float"))]
|
||||||
pub type FLOAT = f64;
|
pub type FLOAT = f64;
|
||||||
|
|
||||||
/// The system floating-point type.
|
/// The system floating-point type.
|
||||||
/// It is defined as [`f32`] since the `f32_float` feature is used.
|
/// It is defined as [`f32`] since the `f32_float` feature is used.
|
||||||
|
/// Not available under `no_float`.
|
||||||
///
|
///
|
||||||
/// If the `f32_float` feature is not used, this will be `f64` instead.
|
/// If the `f32_float` feature is not used, this will be `f64` instead.
|
||||||
///
|
|
||||||
/// Not available under `no_float`.
|
|
||||||
#[cfg(not(feature = "no_float"))]
|
#[cfg(not(feature = "no_float"))]
|
||||||
#[cfg(feature = "f32_float")]
|
#[cfg(feature = "f32_float")]
|
||||||
pub type FLOAT = f32;
|
pub type FLOAT = f32;
|
||||||
@ -180,16 +183,14 @@ pub use fn_args::FuncArgs;
|
|||||||
pub use ast::ScriptFnMetadata;
|
pub use ast::ScriptFnMetadata;
|
||||||
|
|
||||||
/// Variable-sized array of [`Dynamic`] values.
|
/// Variable-sized array of [`Dynamic`] values.
|
||||||
///
|
|
||||||
/// Not available under `no_index`.
|
/// Not available under `no_index`.
|
||||||
#[cfg(not(feature = "no_index"))]
|
#[cfg(not(feature = "no_index"))]
|
||||||
pub type Array = stdlib::vec::Vec<Dynamic>;
|
pub type Array = Vec<Dynamic>;
|
||||||
|
|
||||||
/// Hash map of [`Dynamic`] values with [`ImmutableString`] keys.
|
/// Hash map of [`Dynamic`] values with [`ImmutableString`] keys.
|
||||||
///
|
|
||||||
/// Not available under `no_object`.
|
/// Not available under `no_object`.
|
||||||
#[cfg(not(feature = "no_object"))]
|
#[cfg(not(feature = "no_object"))]
|
||||||
pub type Map = stdlib::collections::BTreeMap<Identifier, Dynamic>;
|
pub type Map = std::collections::BTreeMap<Identifier, Dynamic>;
|
||||||
|
|
||||||
#[cfg(not(feature = "no_module"))]
|
#[cfg(not(feature = "no_module"))]
|
||||||
pub use module::ModuleResolver;
|
pub use module::ModuleResolver;
|
||||||
|
@ -4,23 +4,22 @@ use crate::ast::{FnAccess, Ident};
|
|||||||
use crate::dynamic::Variant;
|
use crate::dynamic::Variant;
|
||||||
use crate::fn_native::{shared_take_or_clone, CallableFunction, FnCallArgs, IteratorFn, SendSync};
|
use crate::fn_native::{shared_take_or_clone, CallableFunction, FnCallArgs, IteratorFn, SendSync};
|
||||||
use crate::fn_register::RegisterNativeFunction;
|
use crate::fn_register::RegisterNativeFunction;
|
||||||
use crate::stdlib::{
|
|
||||||
any::TypeId,
|
|
||||||
boxed::Box,
|
|
||||||
collections::{BTreeMap, BTreeSet},
|
|
||||||
fmt,
|
|
||||||
iter::empty,
|
|
||||||
num::NonZeroUsize,
|
|
||||||
ops::{Add, AddAssign, Deref, DerefMut},
|
|
||||||
string::String,
|
|
||||||
vec::Vec,
|
|
||||||
};
|
|
||||||
use crate::token::Token;
|
use crate::token::Token;
|
||||||
use crate::utils::IdentifierBuilder;
|
use crate::utils::IdentifierBuilder;
|
||||||
use crate::{
|
use crate::{
|
||||||
calc_fn_hash, calc_fn_params_hash, combine_hashes, Dynamic, EvalAltResult, Identifier,
|
calc_fn_hash, calc_fn_params_hash, combine_hashes, Dynamic, EvalAltResult, Identifier,
|
||||||
ImmutableString, NativeCallContext, Position, Shared, StaticVec,
|
ImmutableString, NativeCallContext, Position, Shared, StaticVec,
|
||||||
};
|
};
|
||||||
|
#[cfg(feature = "no_std")]
|
||||||
|
use std::prelude::v1::*;
|
||||||
|
use std::{
|
||||||
|
any::TypeId,
|
||||||
|
collections::{BTreeMap, BTreeSet},
|
||||||
|
fmt,
|
||||||
|
iter::empty,
|
||||||
|
num::NonZeroUsize,
|
||||||
|
ops::{Add, AddAssign, Deref, DerefMut},
|
||||||
|
};
|
||||||
|
|
||||||
#[cfg(not(feature = "no_index"))]
|
#[cfg(not(feature = "no_index"))]
|
||||||
use crate::Array;
|
use crate::Array;
|
||||||
@ -73,7 +72,7 @@ impl FuncInfo {
|
|||||||
let mut sig = format!("{}(", self.name);
|
let mut sig = format!("{}(", self.name);
|
||||||
|
|
||||||
if !self.param_names.is_empty() {
|
if !self.param_names.is_empty() {
|
||||||
let mut params: crate::stdlib::vec::Vec<String> =
|
let mut params: std::vec::Vec<String> =
|
||||||
self.param_names.iter().map(|s| s.as_str().into()).collect();
|
self.param_names.iter().map(|s| s.as_str().into()).collect();
|
||||||
let return_type = params.pop().unwrap_or_else(|| "()".into());
|
let return_type = params.pop().unwrap_or_else(|| "()".into());
|
||||||
sig.push_str(¶ms.join(", "));
|
sig.push_str(¶ms.join(", "));
|
||||||
@ -198,7 +197,7 @@ impl fmt::Debug for Module {
|
|||||||
&self
|
&self
|
||||||
.functions
|
.functions
|
||||||
.values()
|
.values()
|
||||||
.map(|f| crate::stdlib::string::ToString::to_string(&f.func))
|
.map(|f| std::string::ToString::to_string(&f.func))
|
||||||
.collect::<BTreeSet<_>>(),
|
.collect::<BTreeSet<_>>(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -1231,7 +1230,7 @@ impl Module {
|
|||||||
&mut self,
|
&mut self,
|
||||||
filter: impl Fn(FnNamespace, FnAccess, &str, usize) -> bool,
|
filter: impl Fn(FnNamespace, FnAccess, &str, usize) -> bool,
|
||||||
) -> &mut Self {
|
) -> &mut Self {
|
||||||
self.functions = crate::stdlib::mem::take(&mut self.functions)
|
self.functions = std::mem::take(&mut self.functions)
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.filter(|(_, f)| {
|
.filter(|(_, f)| {
|
||||||
if f.func.is_script() {
|
if f.func.is_script() {
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
use crate::stdlib::{boxed::Box, ops::AddAssign, vec::Vec};
|
|
||||||
use crate::{Engine, EvalAltResult, Module, ModuleResolver, Position, Shared};
|
use crate::{Engine, EvalAltResult, Module, ModuleResolver, Position, Shared};
|
||||||
|
use std::ops::AddAssign;
|
||||||
|
#[cfg(feature = "no_std")]
|
||||||
|
use std::prelude::v1::*;
|
||||||
|
|
||||||
/// [Module] resolution service that holds a collection of module resolvers,
|
/// [Module] resolution service that holds a collection of module resolvers,
|
||||||
/// to be searched in sequential order.
|
/// to be searched in sequential order.
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
use crate::stdlib::boxed::Box;
|
|
||||||
use crate::{Engine, EvalAltResult, Module, ModuleResolver, Position, Shared};
|
use crate::{Engine, EvalAltResult, Module, ModuleResolver, Position, Shared};
|
||||||
|
#[cfg(feature = "no_std")]
|
||||||
|
use std::prelude::v1::*;
|
||||||
|
|
||||||
/// Empty/disabled [module][Module] resolution service that acts as a dummy.
|
/// Empty/disabled [module][Module] resolution service that acts as a dummy.
|
||||||
///
|
///
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
use crate::stdlib::{
|
use crate::{Engine, EvalAltResult, Identifier, Module, ModuleResolver, Position, Shared};
|
||||||
boxed::Box,
|
#[cfg(feature = "no_std")]
|
||||||
|
use std::prelude::v1::*;
|
||||||
|
use std::{
|
||||||
collections::BTreeMap,
|
collections::BTreeMap,
|
||||||
io::Error as IoError,
|
io::Error as IoError,
|
||||||
path::{Path, PathBuf},
|
path::{Path, PathBuf},
|
||||||
};
|
};
|
||||||
use crate::{Engine, EvalAltResult, Identifier, Module, ModuleResolver, Position, Shared};
|
|
||||||
|
|
||||||
pub const RHAI_SCRIPT_EXTENSION: &str = "rhai";
|
pub const RHAI_SCRIPT_EXTENSION: &str = "rhai";
|
||||||
|
|
||||||
@ -45,9 +46,9 @@ pub struct FileModuleResolver {
|
|||||||
cache_enabled: bool,
|
cache_enabled: bool,
|
||||||
|
|
||||||
#[cfg(not(feature = "sync"))]
|
#[cfg(not(feature = "sync"))]
|
||||||
cache: crate::stdlib::cell::RefCell<BTreeMap<PathBuf, Shared<Module>>>,
|
cache: std::cell::RefCell<BTreeMap<PathBuf, Shared<Module>>>,
|
||||||
#[cfg(feature = "sync")]
|
#[cfg(feature = "sync")]
|
||||||
cache: crate::stdlib::sync::RwLock<BTreeMap<PathBuf, Shared<Module>>>,
|
cache: std::sync::RwLock<BTreeMap<PathBuf, Shared<Module>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for FileModuleResolver {
|
impl Default for FileModuleResolver {
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
use crate::fn_native::SendSync;
|
use crate::fn_native::SendSync;
|
||||||
use crate::stdlib::boxed::Box;
|
|
||||||
use crate::{Engine, EvalAltResult, Module, Position, Shared, AST};
|
use crate::{Engine, EvalAltResult, Module, Position, Shared, AST};
|
||||||
|
#[cfg(feature = "no_std")]
|
||||||
|
use std::prelude::v1::*;
|
||||||
|
|
||||||
mod dummy;
|
mod dummy;
|
||||||
pub use dummy::DummyModuleResolver;
|
pub use dummy::DummyModuleResolver;
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
use crate::stdlib::{boxed::Box, collections::BTreeMap, ops::AddAssign};
|
|
||||||
use crate::{Engine, EvalAltResult, Identifier, Module, ModuleResolver, Position, Shared};
|
use crate::{Engine, EvalAltResult, Identifier, Module, ModuleResolver, Position, Shared};
|
||||||
|
#[cfg(feature = "no_std")]
|
||||||
|
use std::prelude::v1::*;
|
||||||
|
use std::{collections::BTreeMap, ops::AddAssign};
|
||||||
|
|
||||||
/// A static [module][Module] resolution service that serves [modules][Module] added into it.
|
/// A static [module][Module] resolution service that serves [modules][Module] added into it.
|
||||||
///
|
///
|
||||||
|
@ -5,21 +5,19 @@ use crate::dynamic::AccessMode;
|
|||||||
use crate::engine::{KEYWORD_DEBUG, KEYWORD_EVAL, KEYWORD_FN_PTR, KEYWORD_PRINT, KEYWORD_TYPE_OF};
|
use crate::engine::{KEYWORD_DEBUG, KEYWORD_EVAL, KEYWORD_FN_PTR, KEYWORD_PRINT, KEYWORD_TYPE_OF};
|
||||||
use crate::fn_builtin::get_builtin_binary_op_fn;
|
use crate::fn_builtin::get_builtin_binary_op_fn;
|
||||||
use crate::parser::map_dynamic_to_expr;
|
use crate::parser::map_dynamic_to_expr;
|
||||||
use crate::stdlib::{
|
|
||||||
any::TypeId,
|
|
||||||
boxed::Box,
|
|
||||||
hash::{Hash, Hasher},
|
|
||||||
iter::empty,
|
|
||||||
mem,
|
|
||||||
string::{String, ToString},
|
|
||||||
vec,
|
|
||||||
vec::Vec,
|
|
||||||
};
|
|
||||||
use crate::utils::get_hasher;
|
use crate::utils::get_hasher;
|
||||||
use crate::{
|
use crate::{
|
||||||
calc_fn_hash, calc_fn_params_hash, combine_hashes, Dynamic, Engine, ImmutableString, Module,
|
calc_fn_hash, calc_fn_params_hash, combine_hashes, Dynamic, Engine, ImmutableString, Module,
|
||||||
Position, Scope, StaticVec, AST,
|
Position, Scope, StaticVec, AST,
|
||||||
};
|
};
|
||||||
|
#[cfg(feature = "no_std")]
|
||||||
|
use std::prelude::v1::*;
|
||||||
|
use std::{
|
||||||
|
any::TypeId,
|
||||||
|
hash::{Hash, Hasher},
|
||||||
|
iter::empty,
|
||||||
|
mem,
|
||||||
|
};
|
||||||
|
|
||||||
/// Level of optimization performed.
|
/// Level of optimization performed.
|
||||||
#[derive(Debug, Eq, PartialEq, Hash, Clone, Copy)]
|
#[derive(Debug, Eq, PartialEq, Hash, Clone, Copy)]
|
||||||
@ -947,7 +945,7 @@ fn optimize_expr(expr: &mut Expr, state: &mut State) {
|
|||||||
""
|
""
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(result) = call_fn_with_constant_arguments(&state, x.name.as_ref(), arg_values.as_mut())
|
if let Some(result) = call_fn_with_constant_arguments(&state, x.name.as_ref(), &mut arg_values)
|
||||||
.or_else(|| {
|
.or_else(|| {
|
||||||
if !arg_for_type_of.is_empty() {
|
if !arg_for_type_of.is_empty() {
|
||||||
// Handle `type_of()`
|
// Handle `type_of()`
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
#![allow(non_snake_case)]
|
#![allow(non_snake_case)]
|
||||||
|
|
||||||
use crate::plugin::*;
|
use crate::plugin::*;
|
||||||
use crate::stdlib::{format, string::String};
|
|
||||||
use crate::{def_package, EvalAltResult, Position, INT};
|
use crate::{def_package, EvalAltResult, Position, INT};
|
||||||
|
#[cfg(feature = "no_std")]
|
||||||
|
use std::prelude::v1::*;
|
||||||
|
|
||||||
#[cfg(not(feature = "no_float"))]
|
#[cfg(not(feature = "no_float"))]
|
||||||
use crate::FLOAT;
|
use crate::FLOAT;
|
||||||
|
@ -3,8 +3,10 @@
|
|||||||
|
|
||||||
use crate::engine::OP_EQUALS;
|
use crate::engine::OP_EQUALS;
|
||||||
use crate::plugin::*;
|
use crate::plugin::*;
|
||||||
use crate::stdlib::{any::TypeId, boxed::Box, cmp::Ordering, mem, string::ToString};
|
|
||||||
use crate::{def_package, Array, Dynamic, EvalAltResult, FnPtr, NativeCallContext, Position, INT};
|
use crate::{def_package, Array, Dynamic, EvalAltResult, FnPtr, NativeCallContext, Position, INT};
|
||||||
|
#[cfg(feature = "no_std")]
|
||||||
|
use std::prelude::v1::*;
|
||||||
|
use std::{any::TypeId, cmp::Ordering, mem};
|
||||||
|
|
||||||
def_package!(crate:BasicArrayPackage:"Basic array utilities.", lib, {
|
def_package!(crate:BasicArrayPackage:"Basic array utilities.", lib, {
|
||||||
combine_with_exported_module!(lib, "array", array_functions);
|
combine_with_exported_module!(lib, "array", array_functions);
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
use crate::plugin::*;
|
use crate::plugin::*;
|
||||||
use crate::{def_package, FnPtr, ImmutableString, NativeCallContext};
|
use crate::{def_package, FnPtr, ImmutableString, NativeCallContext};
|
||||||
|
#[cfg(feature = "no_std")]
|
||||||
|
use std::prelude::v1::*;
|
||||||
|
|
||||||
def_package!(crate:BasicFnPackage:"Basic Fn functions.", lib, {
|
def_package!(crate:BasicFnPackage:"Basic Fn functions.", lib, {
|
||||||
combine_with_exported_module!(lib, "FnPtr", fn_ptr_functions);
|
combine_with_exported_module!(lib, "FnPtr", fn_ptr_functions);
|
||||||
@ -34,7 +36,8 @@ mod fn_ptr_functions {
|
|||||||
#[cfg(not(feature = "no_index"))]
|
#[cfg(not(feature = "no_index"))]
|
||||||
#[cfg(not(feature = "no_object"))]
|
#[cfg(not(feature = "no_object"))]
|
||||||
fn collect_fn_metadata(ctx: NativeCallContext) -> crate::Array {
|
fn collect_fn_metadata(ctx: NativeCallContext) -> crate::Array {
|
||||||
use crate::{ast::ScriptFnDef, stdlib::collections::BTreeSet, Array, Identifier, Map};
|
use crate::{ast::ScriptFnDef, Array, Identifier, Map};
|
||||||
|
use std::collections::BTreeSet;
|
||||||
|
|
||||||
// Create a metadata record for a function.
|
// Create a metadata record for a function.
|
||||||
fn make_metadata(
|
fn make_metadata(
|
||||||
|
@ -1,15 +1,17 @@
|
|||||||
use crate::dynamic::Variant;
|
use crate::dynamic::Variant;
|
||||||
use crate::stdlib::{boxed::Box, ops::Range};
|
|
||||||
use crate::{def_package, EvalAltResult, INT};
|
use crate::{def_package, EvalAltResult, INT};
|
||||||
|
use std::ops::Range;
|
||||||
|
#[cfg(feature = "no_std")]
|
||||||
|
use std::prelude::v1::*;
|
||||||
|
|
||||||
#[cfg(not(feature = "unchecked"))]
|
#[cfg(not(feature = "unchecked"))]
|
||||||
use crate::stdlib::string::ToString;
|
use std::string::ToString;
|
||||||
|
|
||||||
#[cfg(not(feature = "unchecked"))]
|
#[cfg(not(feature = "unchecked"))]
|
||||||
use num_traits::{CheckedAdd as Add, CheckedSub as Sub};
|
use num_traits::{CheckedAdd as Add, CheckedSub as Sub};
|
||||||
|
|
||||||
#[cfg(feature = "unchecked")]
|
#[cfg(feature = "unchecked")]
|
||||||
use crate::stdlib::ops::{Add, Sub};
|
use std::ops::{Add, Sub};
|
||||||
|
|
||||||
fn get_range<T: Variant + Clone>(from: T, to: T) -> Result<Range<T>, Box<EvalAltResult>> {
|
fn get_range<T: Variant + Clone>(from: T, to: T) -> Result<Range<T>, Box<EvalAltResult>> {
|
||||||
Ok(from..to)
|
Ok(from..to)
|
||||||
@ -207,7 +209,7 @@ def_package!(crate:BasicIteratorPackage:"Basic range iterators.", lib, {
|
|||||||
pub fn new(from: Decimal, to: Decimal, step: Decimal) -> Result<Self, Box<EvalAltResult>> {
|
pub fn new(from: Decimal, to: Decimal, step: Decimal) -> Result<Self, Box<EvalAltResult>> {
|
||||||
#[cfg(not(feature = "unchecked"))]
|
#[cfg(not(feature = "unchecked"))]
|
||||||
if step.is_zero() {
|
if step.is_zero() {
|
||||||
use crate::stdlib::string::ToString;
|
use std::string::ToString;
|
||||||
|
|
||||||
return EvalAltResult::ErrorInFunctionCall("range".to_string(), "".to_string(),
|
return EvalAltResult::ErrorInFunctionCall("range".to_string(), "".to_string(),
|
||||||
Box::new(EvalAltResult::ErrorArithmetic("step value cannot be zero".to_string(), crate::Position::NONE)),
|
Box::new(EvalAltResult::ErrorArithmetic("step value cannot be zero".to_string(), crate::Position::NONE)),
|
||||||
@ -251,7 +253,7 @@ def_package!(crate:BasicIteratorPackage:"Basic range iterators.", lib, {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl crate::stdlib::iter::FusedIterator for StepDecimalRange {}
|
impl std::iter::FusedIterator for StepDecimalRange {}
|
||||||
|
|
||||||
lib.set_iterator::<StepDecimalRange>();
|
lib.set_iterator::<StepDecimalRange>();
|
||||||
|
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
use crate::def_package;
|
use crate::def_package;
|
||||||
use crate::plugin::*;
|
use crate::plugin::*;
|
||||||
|
#[cfg(feature = "no_std")]
|
||||||
|
use std::prelude::v1::*;
|
||||||
|
|
||||||
#[cfg(any(
|
#[cfg(any(
|
||||||
not(feature = "no_float"),
|
not(feature = "no_float"),
|
||||||
|
@ -3,6 +3,8 @@
|
|||||||
use crate::engine::OP_EQUALS;
|
use crate::engine::OP_EQUALS;
|
||||||
use crate::plugin::*;
|
use crate::plugin::*;
|
||||||
use crate::{def_package, Dynamic, ImmutableString, Map, INT};
|
use crate::{def_package, Dynamic, ImmutableString, Map, INT};
|
||||||
|
#[cfg(feature = "no_std")]
|
||||||
|
use std::prelude::v1::*;
|
||||||
|
|
||||||
#[cfg(not(feature = "no_index"))]
|
#[cfg(not(feature = "no_index"))]
|
||||||
use crate::Array;
|
use crate::Array;
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
use crate::plugin::*;
|
use crate::plugin::*;
|
||||||
use crate::{def_package, Position, INT};
|
use crate::{def_package, Position, INT};
|
||||||
|
#[cfg(feature = "no_std")]
|
||||||
|
use std::prelude::v1::*;
|
||||||
|
|
||||||
#[cfg(not(feature = "no_float"))]
|
#[cfg(not(feature = "no_float"))]
|
||||||
use crate::FLOAT;
|
use crate::FLOAT;
|
||||||
@ -9,9 +11,6 @@ use crate::FLOAT;
|
|||||||
#[cfg(not(feature = "no_float"))]
|
#[cfg(not(feature = "no_float"))]
|
||||||
use crate::result::EvalAltResult;
|
use crate::result::EvalAltResult;
|
||||||
|
|
||||||
#[cfg(not(feature = "no_float"))]
|
|
||||||
use crate::stdlib::format;
|
|
||||||
|
|
||||||
#[cfg(feature = "no_std")]
|
#[cfg(feature = "no_std")]
|
||||||
#[cfg(not(feature = "no_float"))]
|
#[cfg(not(feature = "no_float"))]
|
||||||
use num_traits::Float;
|
use num_traits::Float;
|
||||||
@ -194,16 +193,16 @@ mod float_functions {
|
|||||||
#[rhai_fn(name = "E")]
|
#[rhai_fn(name = "E")]
|
||||||
pub fn e() -> FLOAT {
|
pub fn e() -> FLOAT {
|
||||||
#[cfg(not(feature = "f32_float"))]
|
#[cfg(not(feature = "f32_float"))]
|
||||||
return crate::stdlib::f64::consts::E;
|
return std::f64::consts::E;
|
||||||
#[cfg(feature = "f32_float")]
|
#[cfg(feature = "f32_float")]
|
||||||
return crate::stdlib::f32::consts::E;
|
return std::f32::consts::E;
|
||||||
}
|
}
|
||||||
#[rhai_fn(name = "PI")]
|
#[rhai_fn(name = "PI")]
|
||||||
pub fn pi() -> FLOAT {
|
pub fn pi() -> FLOAT {
|
||||||
#[cfg(not(feature = "f32_float"))]
|
#[cfg(not(feature = "f32_float"))]
|
||||||
return crate::stdlib::f64::consts::PI;
|
return std::f64::consts::PI;
|
||||||
#[cfg(feature = "f32_float")]
|
#[cfg(feature = "f32_float")]
|
||||||
return crate::stdlib::f32::consts::PI;
|
return std::f32::consts::PI;
|
||||||
}
|
}
|
||||||
pub fn to_radians(x: FLOAT) -> FLOAT {
|
pub fn to_radians(x: FLOAT) -> FLOAT {
|
||||||
x.to_radians()
|
x.to_radians()
|
||||||
@ -304,11 +303,11 @@ mod float_functions {
|
|||||||
#[cfg(feature = "decimal")]
|
#[cfg(feature = "decimal")]
|
||||||
#[export_module]
|
#[export_module]
|
||||||
mod decimal_functions {
|
mod decimal_functions {
|
||||||
use crate::stdlib::convert::TryFrom;
|
|
||||||
use rust_decimal::{
|
use rust_decimal::{
|
||||||
prelude::{FromStr, RoundingStrategy},
|
prelude::{FromStr, RoundingStrategy},
|
||||||
Decimal,
|
Decimal,
|
||||||
};
|
};
|
||||||
|
use std::convert::TryFrom;
|
||||||
|
|
||||||
#[rhai_fn(name = "floor", get = "floor")]
|
#[rhai_fn(name = "floor", get = "floor")]
|
||||||
pub fn floor(x: Decimal) -> Decimal {
|
pub fn floor(x: Decimal) -> Decimal {
|
||||||
|
@ -3,6 +3,8 @@ use super::fn_basic::BasicFnPackage;
|
|||||||
use super::iter_basic::BasicIteratorPackage;
|
use super::iter_basic::BasicIteratorPackage;
|
||||||
use super::logic::LogicPackage;
|
use super::logic::LogicPackage;
|
||||||
use super::string_basic::BasicStringPackage;
|
use super::string_basic::BasicStringPackage;
|
||||||
|
#[cfg(feature = "no_std")]
|
||||||
|
use std::prelude::v1::*;
|
||||||
|
|
||||||
use crate::def_package;
|
use crate::def_package;
|
||||||
|
|
||||||
|
@ -7,6 +7,8 @@ use super::pkg_core::CorePackage;
|
|||||||
use super::string_more::MoreStringPackage;
|
use super::string_more::MoreStringPackage;
|
||||||
#[cfg(not(feature = "no_std"))]
|
#[cfg(not(feature = "no_std"))]
|
||||||
use super::time_basic::BasicTimePackage;
|
use super::time_basic::BasicTimePackage;
|
||||||
|
#[cfg(feature = "no_std")]
|
||||||
|
use std::prelude::v1::*;
|
||||||
|
|
||||||
use crate::def_package;
|
use crate::def_package;
|
||||||
|
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
#![allow(non_snake_case)]
|
#![allow(non_snake_case)]
|
||||||
|
|
||||||
use crate::plugin::*;
|
use crate::plugin::*;
|
||||||
use crate::stdlib::{format, string::ToString};
|
|
||||||
use crate::{def_package, FnPtr};
|
use crate::{def_package, FnPtr};
|
||||||
|
#[cfg(feature = "no_std")]
|
||||||
|
use std::prelude::v1::*;
|
||||||
|
|
||||||
#[cfg(not(feature = "no_index"))]
|
#[cfg(not(feature = "no_index"))]
|
||||||
use crate::Array;
|
use crate::Array;
|
||||||
@ -69,10 +70,6 @@ mod print_debug_functions {
|
|||||||
|
|
||||||
#[cfg(not(feature = "no_float"))]
|
#[cfg(not(feature = "no_float"))]
|
||||||
pub mod float_functions {
|
pub mod float_functions {
|
||||||
#[cfg(feature = "no_std")]
|
|
||||||
#[cfg(not(feature = "no_float"))]
|
|
||||||
use num_traits::Float;
|
|
||||||
|
|
||||||
use crate::ast::FloatWrapper;
|
use crate::ast::FloatWrapper;
|
||||||
|
|
||||||
#[rhai_fn(name = "print", name = "to_string")]
|
#[rhai_fn(name = "print", name = "to_string")]
|
||||||
@ -106,7 +103,7 @@ mod print_debug_functions {
|
|||||||
)]
|
)]
|
||||||
pub fn format_array(ctx: NativeCallContext, array: &mut Array) -> ImmutableString {
|
pub fn format_array(ctx: NativeCallContext, array: &mut Array) -> ImmutableString {
|
||||||
let len = array.len();
|
let len = array.len();
|
||||||
let mut result = crate::stdlib::string::String::with_capacity(len * 5 + 2);
|
let mut result = std::string::String::with_capacity(len * 5 + 2);
|
||||||
result.push_str("[");
|
result.push_str("[");
|
||||||
|
|
||||||
array.iter_mut().enumerate().for_each(|(i, x)| {
|
array.iter_mut().enumerate().for_each(|(i, x)| {
|
||||||
@ -133,7 +130,7 @@ mod print_debug_functions {
|
|||||||
)]
|
)]
|
||||||
pub fn format_map(ctx: NativeCallContext, map: &mut Map) -> ImmutableString {
|
pub fn format_map(ctx: NativeCallContext, map: &mut Map) -> ImmutableString {
|
||||||
let len = map.len();
|
let len = map.len();
|
||||||
let mut result = crate::stdlib::string::String::with_capacity(len * 5 + 3);
|
let mut result = std::string::String::with_capacity(len * 5 + 3);
|
||||||
result.push_str("#{");
|
result.push_str("#{");
|
||||||
|
|
||||||
map.iter_mut().enumerate().for_each(|(i, (k, v))| {
|
map.iter_mut().enumerate().for_each(|(i, (k, v))| {
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
#![allow(non_snake_case)]
|
#![allow(non_snake_case)]
|
||||||
|
|
||||||
use crate::plugin::*;
|
use crate::plugin::*;
|
||||||
use crate::stdlib::{
|
|
||||||
any::TypeId, boxed::Box, format, mem, string::String, string::ToString, vec::Vec,
|
|
||||||
};
|
|
||||||
use crate::{def_package, Dynamic, ImmutableString, StaticVec, INT};
|
use crate::{def_package, Dynamic, ImmutableString, StaticVec, INT};
|
||||||
|
#[cfg(feature = "no_std")]
|
||||||
|
use std::prelude::v1::*;
|
||||||
|
use std::{any::TypeId, mem};
|
||||||
|
|
||||||
use super::string_basic::{print_with_func, FUNC_TO_STRING};
|
use super::string_basic::{print_with_func, FUNC_TO_STRING};
|
||||||
|
|
||||||
@ -422,7 +422,6 @@ mod string_functions {
|
|||||||
|
|
||||||
#[cfg(not(feature = "no_index"))]
|
#[cfg(not(feature = "no_index"))]
|
||||||
pub mod arrays {
|
pub mod arrays {
|
||||||
use crate::stdlib::vec;
|
|
||||||
use crate::{Array, ImmutableString};
|
use crate::{Array, ImmutableString};
|
||||||
|
|
||||||
#[rhai_fn(name = "split")]
|
#[rhai_fn(name = "split")]
|
||||||
|
@ -2,14 +2,15 @@
|
|||||||
|
|
||||||
use super::{arithmetic::make_err as make_arithmetic_err, math_basic::MAX_INT};
|
use super::{arithmetic::make_err as make_arithmetic_err, math_basic::MAX_INT};
|
||||||
use crate::plugin::*;
|
use crate::plugin::*;
|
||||||
use crate::stdlib::boxed::Box;
|
|
||||||
use crate::{def_package, Dynamic, EvalAltResult, INT};
|
use crate::{def_package, Dynamic, EvalAltResult, INT};
|
||||||
|
#[cfg(feature = "no_std")]
|
||||||
|
use std::prelude::v1::*;
|
||||||
|
|
||||||
#[cfg(not(feature = "no_float"))]
|
#[cfg(not(feature = "no_float"))]
|
||||||
use crate::FLOAT;
|
use crate::FLOAT;
|
||||||
|
|
||||||
#[cfg(not(any(target_arch = "wasm32", target_arch = "wasm64")))]
|
#[cfg(not(any(target_arch = "wasm32", target_arch = "wasm64")))]
|
||||||
use crate::stdlib::time::{Duration, Instant};
|
use std::time::{Duration, Instant};
|
||||||
|
|
||||||
#[cfg(any(target_arch = "wasm32", target_arch = "wasm64"))]
|
#[cfg(any(target_arch = "wasm32", target_arch = "wasm64"))]
|
||||||
use instant::{Duration, Instant};
|
use instant::{Duration, Instant};
|
||||||
|
@ -1,12 +1,13 @@
|
|||||||
//! Module containing error definitions for the parsing process.
|
//! Module containing error definitions for the parsing process.
|
||||||
|
|
||||||
use crate::stdlib::{
|
|
||||||
boxed::Box,
|
|
||||||
error::Error,
|
|
||||||
fmt,
|
|
||||||
string::{String, ToString},
|
|
||||||
};
|
|
||||||
use crate::{EvalAltResult, Position};
|
use crate::{EvalAltResult, Position};
|
||||||
|
#[cfg(feature = "no_std")]
|
||||||
|
use core_error::Error;
|
||||||
|
#[cfg(not(feature = "no_std"))]
|
||||||
|
use std::error::Error;
|
||||||
|
use std::fmt;
|
||||||
|
#[cfg(feature = "no_std")]
|
||||||
|
use std::prelude::v1::*;
|
||||||
|
|
||||||
/// _(INTERNALS)_ Error encountered when tokenizing the script text.
|
/// _(INTERNALS)_ Error encountered when tokenizing the script text.
|
||||||
/// Exported under the `internals` feature only.
|
/// Exported under the `internals` feature only.
|
||||||
|
@ -9,17 +9,6 @@ use crate::engine::{Precedence, KEYWORD_THIS, OP_CONTAINS};
|
|||||||
use crate::module::NamespaceRef;
|
use crate::module::NamespaceRef;
|
||||||
use crate::optimize::optimize_into_ast;
|
use crate::optimize::optimize_into_ast;
|
||||||
use crate::optimize::OptimizationLevel;
|
use crate::optimize::OptimizationLevel;
|
||||||
use crate::stdlib::{
|
|
||||||
boxed::Box,
|
|
||||||
collections::BTreeMap,
|
|
||||||
format,
|
|
||||||
hash::{Hash, Hasher},
|
|
||||||
iter::empty,
|
|
||||||
num::{NonZeroU8, NonZeroUsize},
|
|
||||||
string::ToString,
|
|
||||||
vec,
|
|
||||||
vec::Vec,
|
|
||||||
};
|
|
||||||
use crate::syntax::{CustomSyntax, MARKER_BLOCK, MARKER_EXPR, MARKER_IDENT};
|
use crate::syntax::{CustomSyntax, MARKER_BLOCK, MARKER_EXPR, MARKER_IDENT};
|
||||||
use crate::token::{
|
use crate::token::{
|
||||||
is_keyword_function, is_valid_identifier, Token, TokenStream, TokenizerControl,
|
is_keyword_function, is_valid_identifier, Token, TokenStream, TokenizerControl,
|
||||||
@ -29,6 +18,14 @@ use crate::{
|
|||||||
calc_fn_hash, Dynamic, Engine, Identifier, LexError, ParseError, ParseErrorType, Position,
|
calc_fn_hash, Dynamic, Engine, Identifier, LexError, ParseError, ParseErrorType, Position,
|
||||||
Scope, Shared, StaticVec, AST,
|
Scope, Shared, StaticVec, AST,
|
||||||
};
|
};
|
||||||
|
#[cfg(feature = "no_std")]
|
||||||
|
use std::prelude::v1::*;
|
||||||
|
use std::{
|
||||||
|
collections::BTreeMap,
|
||||||
|
hash::{Hash, Hasher},
|
||||||
|
iter::empty,
|
||||||
|
num::{NonZeroU8, NonZeroUsize},
|
||||||
|
};
|
||||||
|
|
||||||
#[cfg(not(feature = "no_float"))]
|
#[cfg(not(feature = "no_float"))]
|
||||||
use crate::FLOAT;
|
use crate::FLOAT;
|
||||||
@ -381,7 +378,7 @@ fn parse_fn_call(
|
|||||||
(Token::RightParen, _) => {
|
(Token::RightParen, _) => {
|
||||||
eat_token(input, Token::RightParen);
|
eat_token(input, Token::RightParen);
|
||||||
|
|
||||||
let hash = if let Some(modules) = namespace.as_mut() {
|
let hash = if let Some(ref mut modules) = namespace {
|
||||||
#[cfg(not(feature = "no_module"))]
|
#[cfg(not(feature = "no_module"))]
|
||||||
modules.set_index(state.find_module(&modules[0].name));
|
modules.set_index(state.find_module(&modules[0].name));
|
||||||
|
|
||||||
@ -2501,7 +2498,7 @@ fn parse_stmt(
|
|||||||
#[cfg(not(feature = "no_function"))]
|
#[cfg(not(feature = "no_function"))]
|
||||||
#[cfg(feature = "metadata")]
|
#[cfg(feature = "metadata")]
|
||||||
let comments = {
|
let comments = {
|
||||||
let mut comments: StaticVec<crate::stdlib::string::String> = Default::default();
|
let mut comments: StaticVec<std::string::String> = Default::default();
|
||||||
let mut comments_pos = Position::NONE;
|
let mut comments_pos = Position::NONE;
|
||||||
|
|
||||||
// Handle doc-comments.
|
// Handle doc-comments.
|
||||||
@ -2756,7 +2753,7 @@ fn parse_fn(
|
|||||||
mut settings: ParseSettings,
|
mut settings: ParseSettings,
|
||||||
#[cfg(not(feature = "no_function"))]
|
#[cfg(not(feature = "no_function"))]
|
||||||
#[cfg(feature = "metadata")]
|
#[cfg(feature = "metadata")]
|
||||||
comments: StaticVec<crate::stdlib::string::String>,
|
comments: StaticVec<std::string::String>,
|
||||||
) -> Result<ScriptFnDef, ParseError> {
|
) -> Result<ScriptFnDef, ParseError> {
|
||||||
#[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)?;
|
||||||
|
@ -1,11 +1,13 @@
|
|||||||
//! Module defining macros for developing _plugins_.
|
//! Module defining macros for developing _plugins_.
|
||||||
|
|
||||||
pub use crate::fn_native::{CallableFunction, FnCallArgs};
|
pub use crate::fn_native::{CallableFunction, FnCallArgs};
|
||||||
pub use crate::stdlib::{any::TypeId, boxed::Box, format, mem, string::ToString};
|
|
||||||
pub use crate::{
|
pub use crate::{
|
||||||
Dynamic, Engine, EvalAltResult, FnAccess, FnNamespace, ImmutableString, Module,
|
Dynamic, Engine, EvalAltResult, FnAccess, FnNamespace, ImmutableString, Module,
|
||||||
NativeCallContext, Position,
|
NativeCallContext, Position,
|
||||||
};
|
};
|
||||||
|
#[cfg(feature = "no_std")]
|
||||||
|
use std::prelude::v1::*;
|
||||||
|
pub use std::{any::TypeId, mem};
|
||||||
pub type RhaiResult = Result<Dynamic, Box<EvalAltResult>>;
|
pub type RhaiResult = Result<Dynamic, Box<EvalAltResult>>;
|
||||||
|
|
||||||
#[cfg(not(features = "no_module"))]
|
#[cfg(not(features = "no_module"))]
|
||||||
|
@ -1,12 +1,13 @@
|
|||||||
//! Module containing error definitions for the evaluation process.
|
//! Module containing error definitions for the evaluation process.
|
||||||
|
|
||||||
use crate::stdlib::{
|
|
||||||
boxed::Box,
|
|
||||||
error::Error,
|
|
||||||
fmt,
|
|
||||||
string::{String, ToString},
|
|
||||||
};
|
|
||||||
use crate::{Dynamic, ImmutableString, ParseErrorType, Position, INT};
|
use crate::{Dynamic, ImmutableString, ParseErrorType, Position, INT};
|
||||||
|
#[cfg(feature = "no_std")]
|
||||||
|
use core_error::Error;
|
||||||
|
#[cfg(not(feature = "no_std"))]
|
||||||
|
use std::error::Error;
|
||||||
|
use std::fmt;
|
||||||
|
#[cfg(feature = "no_std")]
|
||||||
|
use std::prelude::v1::*;
|
||||||
|
|
||||||
/// Evaluation result.
|
/// Evaluation result.
|
||||||
///
|
///
|
||||||
@ -335,11 +336,7 @@ impl EvalAltResult {
|
|||||||
pub(crate) fn dump_fields(&self, map: &mut crate::Map) {
|
pub(crate) fn dump_fields(&self, map: &mut crate::Map) {
|
||||||
map.insert(
|
map.insert(
|
||||||
"error".into(),
|
"error".into(),
|
||||||
crate::stdlib::format!("{:?}", self)
|
format!("{:?}", self).split('(').next().unwrap().into(),
|
||||||
.split('(')
|
|
||||||
.next()
|
|
||||||
.unwrap()
|
|
||||||
.into(),
|
|
||||||
);
|
);
|
||||||
|
|
||||||
match self {
|
match self {
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
//! Module that defines the [`Scope`] type representing a function call-stack scope.
|
//! Module that defines the [`Scope`] type representing a function call-stack scope.
|
||||||
|
|
||||||
use crate::dynamic::{AccessMode, Variant};
|
use crate::dynamic::{AccessMode, Variant};
|
||||||
use crate::stdlib::{borrow::Cow, boxed::Box, iter, vec::Vec};
|
|
||||||
use crate::{Dynamic, Identifier, StaticVec};
|
use crate::{Dynamic, Identifier, StaticVec};
|
||||||
|
#[cfg(feature = "no_std")]
|
||||||
|
use std::prelude::v1::*;
|
||||||
|
use std::{borrow::Cow, iter::Extend};
|
||||||
|
|
||||||
/// Keep a number of entries inline (since [`Dynamic`] is usually small enough).
|
/// Keep a number of entries inline (since [`Dynamic`] is usually small enough).
|
||||||
const SCOPE_SIZE: usize = 16;
|
const SCOPE_SIZE: usize = 16;
|
||||||
@ -498,7 +500,7 @@ impl<'a> Scope<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, K: Into<Cow<'a, str>>> iter::Extend<(K, Dynamic)> for Scope<'a> {
|
impl<'a, K: Into<Cow<'a, str>>> Extend<(K, Dynamic)> for Scope<'a> {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn extend<T: IntoIterator<Item = (K, Dynamic)>>(&mut self, iter: T) {
|
fn extend<T: IntoIterator<Item = (K, Dynamic)>>(&mut self, iter: T) {
|
||||||
iter.into_iter().for_each(|(name, value)| {
|
iter.into_iter().for_each(|(name, value)| {
|
||||||
|
@ -2,10 +2,12 @@
|
|||||||
|
|
||||||
use super::str::StringSliceDeserializer;
|
use super::str::StringSliceDeserializer;
|
||||||
use crate::dynamic::Union;
|
use crate::dynamic::Union;
|
||||||
use crate::stdlib::{any::type_name, boxed::Box, fmt, string::ToString};
|
|
||||||
use crate::{Dynamic, EvalAltResult, ImmutableString, LexError, Position};
|
use crate::{Dynamic, EvalAltResult, ImmutableString, LexError, Position};
|
||||||
use serde::de::{DeserializeSeed, Error, IntoDeserializer, MapAccess, SeqAccess, Visitor};
|
use serde::de::{DeserializeSeed, Error, IntoDeserializer, MapAccess, SeqAccess, Visitor};
|
||||||
use serde::{Deserialize, Deserializer};
|
use serde::{Deserialize, Deserializer};
|
||||||
|
#[cfg(feature = "no_std")]
|
||||||
|
use std::prelude::v1::*;
|
||||||
|
use std::{any::type_name, fmt};
|
||||||
|
|
||||||
#[cfg(not(feature = "no_index"))]
|
#[cfg(not(feature = "no_index"))]
|
||||||
use crate::Array;
|
use crate::Array;
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
//! Implementations of [`serde::Deserialize`].
|
//! Implementations of [`serde::Deserialize`].
|
||||||
|
|
||||||
use crate::stdlib::{fmt, string::ToString};
|
|
||||||
use crate::{Dynamic, ImmutableString, INT};
|
use crate::{Dynamic, ImmutableString, INT};
|
||||||
use serde::de::{Deserialize, Deserializer, Error, Visitor};
|
use serde::de::{Deserialize, Deserializer, Error, Visitor};
|
||||||
|
use std::fmt;
|
||||||
|
#[cfg(feature = "no_std")]
|
||||||
|
use std::prelude::v1::*;
|
||||||
|
|
||||||
#[cfg(not(feature = "no_index"))]
|
#[cfg(not(feature = "no_index"))]
|
||||||
use crate::Array;
|
use crate::Array;
|
||||||
@ -95,8 +97,8 @@ impl<'d> Visitor<'d> for DynamicVisitor {
|
|||||||
#[cfg(feature = "no_float")]
|
#[cfg(feature = "no_float")]
|
||||||
#[cfg(feature = "decimal")]
|
#[cfg(feature = "decimal")]
|
||||||
fn visit_f32<E: Error>(self, v: f32) -> Result<Self::Value, E> {
|
fn visit_f32<E: Error>(self, v: f32) -> Result<Self::Value, E> {
|
||||||
use crate::stdlib::convert::TryFrom;
|
|
||||||
use rust_decimal::Decimal;
|
use rust_decimal::Decimal;
|
||||||
|
use std::convert::TryFrom;
|
||||||
|
|
||||||
Decimal::try_from(v)
|
Decimal::try_from(v)
|
||||||
.map(|v| v.into())
|
.map(|v| v.into())
|
||||||
@ -105,8 +107,8 @@ impl<'d> Visitor<'d> for DynamicVisitor {
|
|||||||
#[cfg(feature = "no_float")]
|
#[cfg(feature = "no_float")]
|
||||||
#[cfg(feature = "decimal")]
|
#[cfg(feature = "decimal")]
|
||||||
fn visit_f64<E: Error>(self, v: f64) -> Result<Self::Value, E> {
|
fn visit_f64<E: Error>(self, v: f64) -> Result<Self::Value, E> {
|
||||||
use crate::stdlib::convert::TryFrom;
|
|
||||||
use rust_decimal::Decimal;
|
use rust_decimal::Decimal;
|
||||||
|
use std::convert::TryFrom;
|
||||||
|
|
||||||
Decimal::try_from(v)
|
Decimal::try_from(v)
|
||||||
.map(|v| v.into())
|
.map(|v| v.into())
|
||||||
|
@ -1,11 +1,8 @@
|
|||||||
use crate::stdlib::{
|
|
||||||
cmp::Ordering,
|
|
||||||
collections::BTreeMap,
|
|
||||||
string::{String, ToString},
|
|
||||||
vec::Vec,
|
|
||||||
};
|
|
||||||
use crate::{Engine, AST};
|
use crate::{Engine, AST};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
#[cfg(feature = "no_std")]
|
||||||
|
use std::prelude::v1::*;
|
||||||
|
use std::{cmp::Ordering, collections::BTreeMap};
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash, Serialize, Deserialize)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
|
@ -1,11 +1,13 @@
|
|||||||
//! Implement serialization support of [`Dynamic`][crate::Dynamic] for [`serde`].
|
//! Implement serialization support of [`Dynamic`][crate::Dynamic] for [`serde`].
|
||||||
|
|
||||||
use crate::stdlib::{boxed::Box, fmt, string::ToString};
|
|
||||||
use crate::{Dynamic, EvalAltResult, Position, RhaiResult};
|
use crate::{Dynamic, EvalAltResult, Position, RhaiResult};
|
||||||
use serde::ser::{
|
use serde::ser::{
|
||||||
Error, SerializeMap, SerializeSeq, SerializeStruct, SerializeTuple, SerializeTupleStruct,
|
Error, SerializeMap, SerializeSeq, SerializeStruct, SerializeTuple, SerializeTupleStruct,
|
||||||
};
|
};
|
||||||
use serde::{Serialize, Serializer};
|
use serde::{Serialize, Serializer};
|
||||||
|
use std::fmt;
|
||||||
|
#[cfg(feature = "no_std")]
|
||||||
|
use std::prelude::v1::*;
|
||||||
|
|
||||||
#[cfg(not(feature = "no_index"))]
|
#[cfg(not(feature = "no_index"))]
|
||||||
use crate::Array;
|
use crate::Array;
|
||||||
@ -220,8 +222,8 @@ impl Serializer for &mut DynamicSerializer {
|
|||||||
#[cfg(feature = "no_float")]
|
#[cfg(feature = "no_float")]
|
||||||
#[cfg(feature = "decimal")]
|
#[cfg(feature = "decimal")]
|
||||||
{
|
{
|
||||||
use crate::stdlib::convert::TryFrom;
|
|
||||||
use rust_decimal::Decimal;
|
use rust_decimal::Decimal;
|
||||||
|
use std::convert::TryFrom;
|
||||||
|
|
||||||
Decimal::try_from(v)
|
Decimal::try_from(v)
|
||||||
.map(|v| v.into())
|
.map(|v| v.into())
|
||||||
@ -236,8 +238,8 @@ impl Serializer for &mut DynamicSerializer {
|
|||||||
#[cfg(feature = "no_float")]
|
#[cfg(feature = "no_float")]
|
||||||
#[cfg(feature = "decimal")]
|
#[cfg(feature = "decimal")]
|
||||||
{
|
{
|
||||||
use crate::stdlib::convert::TryFrom;
|
|
||||||
use rust_decimal::Decimal;
|
use rust_decimal::Decimal;
|
||||||
|
use std::convert::TryFrom;
|
||||||
|
|
||||||
Decimal::try_from(v)
|
Decimal::try_from(v)
|
||||||
.map(|v| v.into())
|
.map(|v| v.into())
|
||||||
@ -539,7 +541,7 @@ impl SerializeMap for DynamicSerializer {
|
|||||||
) -> Result<(), Box<EvalAltResult>> {
|
) -> Result<(), Box<EvalAltResult>> {
|
||||||
#[cfg(not(feature = "no_object"))]
|
#[cfg(not(feature = "no_object"))]
|
||||||
{
|
{
|
||||||
let key = crate::stdlib::mem::take(&mut self._key)
|
let key = std::mem::take(&mut self._key)
|
||||||
.take_immutable_string()
|
.take_immutable_string()
|
||||||
.map_err(|typ| {
|
.map_err(|typ| {
|
||||||
EvalAltResult::ErrorMismatchDataType(
|
EvalAltResult::ErrorMismatchDataType(
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
//! Implementations of [`serde::Serialize`].
|
//! Implementations of [`serde::Serialize`].
|
||||||
|
|
||||||
use crate::dynamic::{Union, Variant};
|
use crate::dynamic::{Union, Variant};
|
||||||
use crate::stdlib::string::ToString;
|
|
||||||
use crate::{Dynamic, ImmutableString};
|
use crate::{Dynamic, ImmutableString};
|
||||||
use serde::ser::{Serialize, Serializer};
|
use serde::ser::{Serialize, Serializer};
|
||||||
|
#[cfg(feature = "no_std")]
|
||||||
|
use std::prelude::v1::*;
|
||||||
|
|
||||||
#[cfg(not(feature = "no_object"))]
|
#[cfg(not(feature = "no_object"))]
|
||||||
use serde::ser::SerializeMap;
|
use serde::ser::SerializeMap;
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
//! Implement deserialization support of [`ImmutableString`][crate::ImmutableString] for [`serde`].
|
//! Implement deserialization support of [`ImmutableString`][crate::ImmutableString] for [`serde`].
|
||||||
|
|
||||||
use crate::stdlib::{any::type_name, boxed::Box};
|
|
||||||
use crate::{EvalAltResult, Position};
|
use crate::{EvalAltResult, Position};
|
||||||
use serde::de::{Deserializer, Visitor};
|
use serde::de::{Deserializer, Visitor};
|
||||||
|
use std::any::type_name;
|
||||||
|
#[cfg(feature = "no_std")]
|
||||||
|
use std::prelude::v1::*;
|
||||||
|
|
||||||
/// Deserializer for `ImmutableString`.
|
/// Deserializer for `ImmutableString`.
|
||||||
pub struct StringSliceDeserializer<'a> {
|
pub struct StringSliceDeserializer<'a> {
|
||||||
|
@ -1,32 +0,0 @@
|
|||||||
//! Helper module which defines most of the needed features from `std` for `no-std` builds.
|
|
||||||
|
|
||||||
#[cfg(feature = "no_std")]
|
|
||||||
mod inner {
|
|
||||||
pub use core::{
|
|
||||||
any, arch, array, ascii, cell, char, clone, cmp, convert, default, f32, f64, ffi, fmt,
|
|
||||||
future, hash, hint, i16, i32, i64, i8, isize, iter, marker, mem, num, ops, option, panic,
|
|
||||||
pin, prelude, ptr, result, slice, str, task, time, u16, u32, u64, u8, usize,
|
|
||||||
};
|
|
||||||
|
|
||||||
#[cfg(not(any(target_arch = "wasm32", target_arch = "wasm64")))]
|
|
||||||
pub use core::{i128, u128};
|
|
||||||
|
|
||||||
#[cfg(feature = "sync")]
|
|
||||||
pub use alloc::sync;
|
|
||||||
|
|
||||||
pub use alloc::{borrow, boxed, format, rc, string, vec};
|
|
||||||
|
|
||||||
pub use core_error as error;
|
|
||||||
|
|
||||||
pub mod collections {
|
|
||||||
pub use alloc::collections::btree_map::BTreeMap;
|
|
||||||
pub use alloc::collections::btree_set::BTreeSet;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(not(feature = "no_std"))]
|
|
||||||
mod inner {
|
|
||||||
pub use std::*;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub use self::inner::*;
|
|
@ -3,12 +3,13 @@
|
|||||||
use crate::ast::Expr;
|
use crate::ast::Expr;
|
||||||
use crate::engine::EvalContext;
|
use crate::engine::EvalContext;
|
||||||
use crate::fn_native::SendSync;
|
use crate::fn_native::SendSync;
|
||||||
use crate::stdlib::{boxed::Box, format, string::ToString};
|
|
||||||
use crate::token::{is_valid_identifier, Token};
|
use crate::token::{is_valid_identifier, Token};
|
||||||
use crate::{
|
use crate::{
|
||||||
Engine, Identifier, ImmutableString, LexError, ParseError, Position, RhaiResult, Shared,
|
Engine, Identifier, ImmutableString, LexError, ParseError, Position, RhaiResult, Shared,
|
||||||
StaticVec,
|
StaticVec,
|
||||||
};
|
};
|
||||||
|
#[cfg(feature = "no_std")]
|
||||||
|
use std::prelude::v1::*;
|
||||||
|
|
||||||
pub const MARKER_EXPR: &str = "$expr$";
|
pub const MARKER_EXPR: &str = "$expr$";
|
||||||
pub const MARKER_BLOCK: &str = "$block$";
|
pub const MARKER_BLOCK: &str = "$block$";
|
||||||
|
@ -4,18 +4,19 @@ use crate::engine::{
|
|||||||
Precedence, KEYWORD_DEBUG, KEYWORD_EVAL, KEYWORD_FN_PTR, KEYWORD_FN_PTR_CALL,
|
Precedence, KEYWORD_DEBUG, KEYWORD_EVAL, KEYWORD_FN_PTR, KEYWORD_FN_PTR_CALL,
|
||||||
KEYWORD_FN_PTR_CURRY, KEYWORD_IS_DEF_VAR, KEYWORD_PRINT, KEYWORD_THIS, KEYWORD_TYPE_OF,
|
KEYWORD_FN_PTR_CURRY, KEYWORD_IS_DEF_VAR, KEYWORD_PRINT, KEYWORD_THIS, KEYWORD_TYPE_OF,
|
||||||
};
|
};
|
||||||
use crate::stdlib::{
|
use crate::{Engine, LexError, StaticVec, INT};
|
||||||
|
#[cfg(feature = "no_std")]
|
||||||
|
use std::prelude::v1::*;
|
||||||
|
use std::{
|
||||||
borrow::Cow,
|
borrow::Cow,
|
||||||
cell::Cell,
|
cell::Cell,
|
||||||
char, fmt, format,
|
char, fmt,
|
||||||
iter::{FusedIterator, Peekable},
|
iter::{FusedIterator, Peekable},
|
||||||
num::NonZeroUsize,
|
num::NonZeroUsize,
|
||||||
ops::{Add, AddAssign},
|
ops::{Add, AddAssign},
|
||||||
rc::Rc,
|
rc::Rc,
|
||||||
str::{Chars, FromStr},
|
str::{Chars, FromStr},
|
||||||
string::{String, ToString},
|
|
||||||
};
|
};
|
||||||
use crate::{Engine, LexError, StaticVec, INT};
|
|
||||||
|
|
||||||
#[cfg(not(feature = "no_float"))]
|
#[cfg(not(feature = "no_float"))]
|
||||||
use crate::{ast::FloatWrapper, FLOAT};
|
use crate::{ast::FloatWrapper, FLOAT};
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
//! A helper module containing unsafe utility functions.
|
//! A helper module containing unsafe utility functions.
|
||||||
|
|
||||||
use crate::dynamic::Variant;
|
use crate::dynamic::Variant;
|
||||||
use crate::stdlib::{
|
#[cfg(feature = "no_std")]
|
||||||
|
use std::prelude::v1::*;
|
||||||
|
use std::{
|
||||||
any::{Any, TypeId},
|
any::{Any, TypeId},
|
||||||
boxed::Box,
|
|
||||||
mem, ptr,
|
mem, ptr,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
19
src/utils.rs
19
src/utils.rs
@ -1,20 +1,19 @@
|
|||||||
//! Module containing various utility types and functions.
|
//! Module containing various utility types and functions.
|
||||||
|
|
||||||
use crate::fn_native::{shared_make_mut, shared_take};
|
use crate::fn_native::{shared_make_mut, shared_take};
|
||||||
use crate::stdlib::{
|
use crate::{Identifier, Shared};
|
||||||
|
#[cfg(feature = "no_std")]
|
||||||
|
use std::prelude::v1::*;
|
||||||
|
use std::{
|
||||||
any::TypeId,
|
any::TypeId,
|
||||||
borrow::Borrow,
|
borrow::Borrow,
|
||||||
boxed::Box,
|
|
||||||
cmp::Ordering,
|
cmp::Ordering,
|
||||||
fmt,
|
fmt,
|
||||||
fmt::{Debug, Display},
|
|
||||||
hash::{BuildHasher, Hash, Hasher},
|
hash::{BuildHasher, Hash, Hasher},
|
||||||
iter::FromIterator,
|
iter::FromIterator,
|
||||||
ops::{Add, AddAssign, Deref, Sub, SubAssign},
|
ops::{Add, AddAssign, Deref, Sub, SubAssign},
|
||||||
str::FromStr,
|
str::FromStr,
|
||||||
string::{String, ToString},
|
|
||||||
};
|
};
|
||||||
use crate::{Identifier, Shared};
|
|
||||||
|
|
||||||
/// A hasher that only takes one single [`u64`] and returns it as a hash key.
|
/// A hasher that only takes one single [`u64`] and returns it as a hash key.
|
||||||
///
|
///
|
||||||
@ -251,17 +250,17 @@ impl<'a> FromIterator<String> for ImmutableString {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display for ImmutableString {
|
impl fmt::Display for ImmutableString {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
Display::fmt(self.0.as_str(), f)
|
fmt::Display::fmt(self.0.as_str(), f)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Debug for ImmutableString {
|
impl fmt::Debug for ImmutableString {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
Debug::fmt(self.0.as_str(), f)
|
fmt::Debug::fmt(self.0.as_str(), f)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -631,7 +630,7 @@ impl ImmutableString {
|
|||||||
/// yet interned.
|
/// yet interned.
|
||||||
#[derive(Debug, Clone, Default, Hash)]
|
#[derive(Debug, Clone, Default, Hash)]
|
||||||
pub struct IdentifierBuilder(
|
pub struct IdentifierBuilder(
|
||||||
#[cfg(feature = "no_smartstring")] crate::stdlib::collections::BTreeSet<Identifier>,
|
#[cfg(feature = "no_smartstring")] std::collections::BTreeSet<Identifier>,
|
||||||
);
|
);
|
||||||
|
|
||||||
impl IdentifierBuilder {
|
impl IdentifierBuilder {
|
||||||
|
Loading…
Reference in New Issue
Block a user