Reduce Rc/Arc wrapping for functions.
This commit is contained in:
parent
ab76a69b12
commit
4a1fd66b9f
@ -3,11 +3,11 @@
|
||||
use crate::any::{Dynamic, Union};
|
||||
use crate::calc_fn_hash;
|
||||
use crate::error::ParseErrorType;
|
||||
use crate::fn_native::{FnCallArgs, PrintCallback, ProgressCallback};
|
||||
use crate::fn_native::{FnCallArgs, PrintCallback, ProgressCallback, SharedFnDef};
|
||||
use crate::module::Module;
|
||||
use crate::optimize::OptimizationLevel;
|
||||
use crate::packages::{CorePackage, Package, PackageLibrary, PackagesCollection, StandardPackage};
|
||||
use crate::parser::{Expr, FnAccess, FnDef, ReturnType, SharedFnDef, Stmt, AST};
|
||||
use crate::parser::{Expr, FnAccess, FnDef, ReturnType, Stmt, AST};
|
||||
use crate::r#unsafe::unsafe_cast_var_name_to_lifetime;
|
||||
use crate::result::EvalAltResult;
|
||||
use crate::scope::{EntryType as ScopeEntryType, Scope};
|
||||
@ -1741,7 +1741,7 @@ impl Engine {
|
||||
let index = scope.len() - 1;
|
||||
state.scope_level += 1;
|
||||
|
||||
for loop_var in func.get_iter_fn()(iter_type) {
|
||||
for loop_var in func(iter_type) {
|
||||
*scope.get_mut(index).0 = loop_var;
|
||||
self.inc_operations(state, stmt.position())?;
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
use crate::any::Dynamic;
|
||||
use crate::parser::{FnDef, SharedFnDef};
|
||||
use crate::parser::FnDef;
|
||||
use crate::result::EvalAltResult;
|
||||
|
||||
use crate::stdlib::{boxed::Box, rc::Rc, sync::Arc};
|
||||
@ -73,15 +73,31 @@ pub trait IteratorCallback: Fn(Dynamic) -> Box<dyn Iterator<Item = Dynamic>> + '
|
||||
#[cfg(not(feature = "sync"))]
|
||||
impl<F: Fn(Dynamic) -> Box<dyn Iterator<Item = Dynamic>> + 'static> IteratorCallback for F {}
|
||||
|
||||
#[cfg(not(feature = "sync"))]
|
||||
pub type SharedNativeFunction = Rc<FnAny>;
|
||||
#[cfg(feature = "sync")]
|
||||
pub type SharedNativeFunction = Arc<FnAny>;
|
||||
|
||||
#[cfg(not(feature = "sync"))]
|
||||
pub type SharedIteratorFn = Rc<IteratorFn>;
|
||||
#[cfg(feature = "sync")]
|
||||
pub type SharedIteratorFn = Arc<IteratorFn>;
|
||||
|
||||
#[cfg(feature = "sync")]
|
||||
pub type SharedFnDef = Arc<FnDef>;
|
||||
#[cfg(not(feature = "sync"))]
|
||||
pub type SharedFnDef = Rc<FnDef>;
|
||||
|
||||
/// A type encapsulating a function callable by Rhai.
|
||||
#[derive(Clone)]
|
||||
pub enum CallableFunction {
|
||||
/// A pure native Rust function with all arguments passed by value.
|
||||
Pure(Box<FnAny>),
|
||||
Pure(SharedNativeFunction),
|
||||
/// A native Rust object method with the first argument passed by reference,
|
||||
/// and the rest passed by value.
|
||||
Method(Box<FnAny>),
|
||||
Method(SharedNativeFunction),
|
||||
/// An iterator function.
|
||||
Iterator(Box<IteratorFn>),
|
||||
Iterator(SharedIteratorFn),
|
||||
/// A script-defined function.
|
||||
Script(SharedFnDef),
|
||||
}
|
||||
@ -90,37 +106,29 @@ impl CallableFunction {
|
||||
/// Is this a pure native Rust function?
|
||||
pub fn is_pure(&self) -> bool {
|
||||
match self {
|
||||
CallableFunction::Pure(_) => true,
|
||||
CallableFunction::Method(_)
|
||||
| CallableFunction::Iterator(_)
|
||||
| CallableFunction::Script(_) => false,
|
||||
Self::Pure(_) => true,
|
||||
Self::Method(_) | Self::Iterator(_) | Self::Script(_) => false,
|
||||
}
|
||||
}
|
||||
/// Is this a pure native Rust method-call?
|
||||
pub fn is_method(&self) -> bool {
|
||||
match self {
|
||||
CallableFunction::Method(_) => true,
|
||||
CallableFunction::Pure(_)
|
||||
| CallableFunction::Iterator(_)
|
||||
| CallableFunction::Script(_) => false,
|
||||
Self::Method(_) => true,
|
||||
Self::Pure(_) | Self::Iterator(_) | Self::Script(_) => false,
|
||||
}
|
||||
}
|
||||
/// Is this an iterator function?
|
||||
pub fn is_iter(&self) -> bool {
|
||||
match self {
|
||||
CallableFunction::Iterator(_) => true,
|
||||
CallableFunction::Pure(_)
|
||||
| CallableFunction::Method(_)
|
||||
| CallableFunction::Script(_) => false,
|
||||
Self::Iterator(_) => true,
|
||||
Self::Pure(_) | Self::Method(_) | Self::Script(_) => false,
|
||||
}
|
||||
}
|
||||
/// Is this a Rhai-scripted function?
|
||||
pub fn is_script(&self) -> bool {
|
||||
match self {
|
||||
CallableFunction::Script(_) => true,
|
||||
CallableFunction::Pure(_)
|
||||
| CallableFunction::Method(_)
|
||||
| CallableFunction::Iterator(_) => false,
|
||||
Self::Script(_) => true,
|
||||
Self::Pure(_) | Self::Method(_) | Self::Iterator(_) => false,
|
||||
}
|
||||
}
|
||||
/// Get a reference to a native Rust function.
|
||||
@ -128,10 +136,10 @@ impl CallableFunction {
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if the `CallableFunction` is not `Pure` or `Method`.
|
||||
pub fn get_native_fn(&self) -> &Box<FnAny> {
|
||||
pub fn get_native_fn(&self) -> &FnAny {
|
||||
match self {
|
||||
CallableFunction::Pure(f) | CallableFunction::Method(f) => f,
|
||||
CallableFunction::Iterator(_) | CallableFunction::Script(_) => panic!(),
|
||||
Self::Pure(f) | Self::Method(f) => f.as_ref(),
|
||||
Self::Iterator(_) | Self::Script(_) => panic!(),
|
||||
}
|
||||
}
|
||||
/// Get a reference to a script-defined function definition.
|
||||
@ -141,10 +149,8 @@ impl CallableFunction {
|
||||
/// Panics if the `CallableFunction` is not `Script`.
|
||||
pub fn get_fn_def(&self) -> &FnDef {
|
||||
match self {
|
||||
CallableFunction::Pure(_)
|
||||
| CallableFunction::Method(_)
|
||||
| CallableFunction::Iterator(_) => panic!(),
|
||||
CallableFunction::Script(f) => f,
|
||||
Self::Pure(_) | Self::Method(_) | Self::Iterator(_) => panic!(),
|
||||
Self::Script(f) => f,
|
||||
}
|
||||
}
|
||||
/// Get a reference to an iterator function.
|
||||
@ -152,19 +158,18 @@ impl CallableFunction {
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if the `CallableFunction` is not `Iterator`.
|
||||
pub fn get_iter_fn(&self) -> &Box<IteratorFn> {
|
||||
pub fn get_iter_fn(&self) -> &IteratorFn {
|
||||
match self {
|
||||
CallableFunction::Pure(_)
|
||||
| CallableFunction::Method(_)
|
||||
| CallableFunction::Script(_) => panic!(),
|
||||
CallableFunction::Iterator(f) => f,
|
||||
Self::Iterator(f) => f.as_ref(),
|
||||
Self::Pure(_) | Self::Method(_) | Self::Script(_) => panic!(),
|
||||
}
|
||||
}
|
||||
/// Create a new `CallableFunction::Pure`.
|
||||
pub fn from_pure(func: Box<FnAny>) -> Self {
|
||||
Self::Pure(func.into())
|
||||
}
|
||||
/// Create a new `CallableFunction::Method`.
|
||||
pub fn from_method(func: Box<FnAny>) -> Self {
|
||||
Self::Method(func.into())
|
||||
}
|
||||
}
|
||||
|
||||
/// A callable function.
|
||||
#[cfg(not(feature = "sync"))]
|
||||
pub type SharedFunction = Rc<CallableFunction>;
|
||||
/// A callable function.
|
||||
#[cfg(feature = "sync")]
|
||||
pub type SharedFunction = Arc<CallableFunction>;
|
||||
|
@ -4,10 +4,7 @@
|
||||
|
||||
use crate::any::{Dynamic, Variant};
|
||||
use crate::engine::Engine;
|
||||
use crate::fn_native::{
|
||||
CallableFunction::{Method, Pure},
|
||||
FnCallArgs,
|
||||
};
|
||||
use crate::fn_native::{CallableFunction, FnAny, FnCallArgs};
|
||||
use crate::parser::FnAccess;
|
||||
use crate::result::EvalAltResult;
|
||||
|
||||
@ -158,7 +155,7 @@ macro_rules! make_func {
|
||||
|
||||
// Map the result
|
||||
$map(r)
|
||||
})
|
||||
}) as Box<FnAny>
|
||||
};
|
||||
}
|
||||
|
||||
@ -184,7 +181,7 @@ pub fn map_result<T: Variant + Clone>(
|
||||
|
||||
macro_rules! def_register {
|
||||
() => {
|
||||
def_register!(imp Pure :);
|
||||
def_register!(imp from_pure :);
|
||||
};
|
||||
(imp $abi:ident : $($par:ident => $mark:ty => $param:ty => $clone:expr),*) => {
|
||||
// ^ function ABI type
|
||||
@ -207,7 +204,7 @@ macro_rules! def_register {
|
||||
fn register_fn(&mut self, name: &str, f: FN) {
|
||||
self.global_module.set_fn(name.to_string(), FnAccess::Public,
|
||||
&[$(TypeId::of::<$par>()),*],
|
||||
$abi(make_func!(f : map_dynamic ; $($par => $clone),*))
|
||||
CallableFunction::$abi(make_func!(f : map_dynamic ; $($par => $clone),*))
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -225,7 +222,7 @@ macro_rules! def_register {
|
||||
fn register_dynamic_fn(&mut self, name: &str, f: FN) {
|
||||
self.global_module.set_fn(name.to_string(), FnAccess::Public,
|
||||
&[$(TypeId::of::<$par>()),*],
|
||||
$abi(make_func!(f : map_identity ; $($par => $clone),*))
|
||||
CallableFunction::$abi(make_func!(f : map_identity ; $($par => $clone),*))
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -244,7 +241,7 @@ macro_rules! def_register {
|
||||
fn register_result_fn(&mut self, name: &str, f: FN) {
|
||||
self.global_module.set_fn(name.to_string(), FnAccess::Public,
|
||||
&[$(TypeId::of::<$par>()),*],
|
||||
$abi(make_func!(f : map_result ; $($par => $clone),*))
|
||||
CallableFunction::$abi(make_func!(f : map_result ; $($par => $clone),*))
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -252,11 +249,11 @@ macro_rules! def_register {
|
||||
//def_register!(imp_pop $($par => $mark => $param),*);
|
||||
};
|
||||
($p0:ident $(, $p:ident)*) => {
|
||||
def_register!(imp Pure : $p0 => $p0 => $p0 => by_value $(, $p => $p => $p => by_value)*);
|
||||
def_register!(imp Method : $p0 => Mut<$p0> => &mut $p0 => by_ref $(, $p => $p => $p => by_value)*);
|
||||
def_register!(imp from_pure : $p0 => $p0 => $p0 => by_value $(, $p => $p => $p => by_value)*);
|
||||
def_register!(imp from_method : $p0 => Mut<$p0> => &mut $p0 => by_ref $(, $p => $p => $p => by_value)*);
|
||||
// ^ CallableFunction
|
||||
// handle the first parameter ^ first parameter passed through
|
||||
// ^ others passed by value (by_value)
|
||||
// handle the first parameter ^ first parameter passed through
|
||||
// ^ others passed by value (by_value)
|
||||
|
||||
// Currently does not support first argument which is a reference, as there will be
|
||||
// conflicting implementations since &T: Any and T: Any cannot be distinguished
|
||||
|
@ -3,11 +3,7 @@
|
||||
use crate::any::{Dynamic, Variant};
|
||||
use crate::calc_fn_hash;
|
||||
use crate::engine::{Engine, FunctionsLib};
|
||||
use crate::fn_native::{
|
||||
CallableFunction,
|
||||
CallableFunction::{Method, Pure},
|
||||
FnCallArgs, IteratorFn, SharedFunction,
|
||||
};
|
||||
use crate::fn_native::{CallableFunction as CF, FnCallArgs, IteratorFn, SharedIteratorFn};
|
||||
use crate::parser::{
|
||||
FnAccess,
|
||||
FnAccess::{Private, Public},
|
||||
@ -27,9 +23,7 @@ use crate::stdlib::{
|
||||
mem,
|
||||
num::NonZeroUsize,
|
||||
ops::{Deref, DerefMut},
|
||||
rc::Rc,
|
||||
string::{String, ToString},
|
||||
sync::Arc,
|
||||
vec,
|
||||
vec::Vec,
|
||||
};
|
||||
@ -53,17 +47,17 @@ pub struct Module {
|
||||
all_variables: HashMap<u64, Dynamic>,
|
||||
|
||||
/// External Rust functions.
|
||||
functions: HashMap<u64, (String, FnAccess, StaticVec<TypeId>, SharedFunction)>,
|
||||
functions: HashMap<u64, (String, FnAccess, StaticVec<TypeId>, CF)>,
|
||||
|
||||
/// Script-defined functions.
|
||||
fn_lib: FunctionsLib,
|
||||
|
||||
/// Iterator functions, keyed by the type producing the iterator.
|
||||
type_iterators: HashMap<TypeId, SharedFunction>,
|
||||
type_iterators: HashMap<TypeId, SharedIteratorFn>,
|
||||
|
||||
/// Flattened collection of all external Rust functions, native or scripted,
|
||||
/// including those in sub-modules.
|
||||
all_functions: HashMap<u64, SharedFunction>,
|
||||
all_functions: HashMap<u64, CF>,
|
||||
}
|
||||
|
||||
impl fmt::Debug for Module {
|
||||
@ -275,13 +269,7 @@ impl Module {
|
||||
/// Set a Rust function into the module, returning a hash key.
|
||||
///
|
||||
/// If there is an existing Rust function of the same hash, it is replaced.
|
||||
pub fn set_fn(
|
||||
&mut self,
|
||||
name: String,
|
||||
access: FnAccess,
|
||||
params: &[TypeId],
|
||||
func: CallableFunction,
|
||||
) -> u64 {
|
||||
pub fn set_fn(&mut self, name: String, access: FnAccess, params: &[TypeId], func: CF) -> u64 {
|
||||
let hash_fn = calc_fn_hash(empty(), &name, params.len(), params.iter().cloned());
|
||||
|
||||
let params = params.into_iter().cloned().collect();
|
||||
@ -312,8 +300,8 @@ impl Module {
|
||||
#[cfg(feature = "sync")] func: impl Fn() -> FuncReturn<T> + Send + Sync + 'static,
|
||||
) -> u64 {
|
||||
let f = move |_: &mut FnCallArgs| func().map(Dynamic::from);
|
||||
let arg_types = [];
|
||||
self.set_fn(name.into(), Public, &arg_types, Pure(Box::new(f)))
|
||||
let args = [];
|
||||
self.set_fn(name.into(), Public, &args, CF::from_pure(Box::new(f)))
|
||||
}
|
||||
|
||||
/// Set a Rust function taking one parameter into the module, returning a hash key.
|
||||
@ -337,8 +325,8 @@ impl Module {
|
||||
) -> u64 {
|
||||
let f =
|
||||
move |args: &mut FnCallArgs| func(mem::take(args[0]).cast::<A>()).map(Dynamic::from);
|
||||
let arg_types = [TypeId::of::<A>()];
|
||||
self.set_fn(name.into(), Public, &arg_types, Pure(Box::new(f)))
|
||||
let args = [TypeId::of::<A>()];
|
||||
self.set_fn(name.into(), Public, &args, CF::from_pure(Box::new(f)))
|
||||
}
|
||||
|
||||
/// Set a Rust function taking one mutable parameter into the module, returning a hash key.
|
||||
@ -363,8 +351,8 @@ impl Module {
|
||||
let f = move |args: &mut FnCallArgs| {
|
||||
func(args[0].downcast_mut::<A>().unwrap()).map(Dynamic::from)
|
||||
};
|
||||
let arg_types = [TypeId::of::<A>()];
|
||||
self.set_fn(name.into(), Public, &arg_types, Method(Box::new(f)))
|
||||
let args = [TypeId::of::<A>()];
|
||||
self.set_fn(name.into(), Public, &args, CF::from_method(Box::new(f)))
|
||||
}
|
||||
|
||||
/// Set a Rust function taking two parameters into the module, returning a hash key.
|
||||
@ -394,8 +382,8 @@ impl Module {
|
||||
|
||||
func(a, b).map(Dynamic::from)
|
||||
};
|
||||
let arg_types = [TypeId::of::<A>(), TypeId::of::<B>()];
|
||||
self.set_fn(name.into(), Public, &arg_types, Pure(Box::new(f)))
|
||||
let args = [TypeId::of::<A>(), TypeId::of::<B>()];
|
||||
self.set_fn(name.into(), Public, &args, CF::from_pure(Box::new(f)))
|
||||
}
|
||||
|
||||
/// Set a Rust function taking two parameters (the first one mutable) into the module,
|
||||
@ -429,8 +417,8 @@ impl Module {
|
||||
|
||||
func(a, b).map(Dynamic::from)
|
||||
};
|
||||
let arg_types = [TypeId::of::<A>(), TypeId::of::<B>()];
|
||||
self.set_fn(name.into(), Public, &arg_types, Method(Box::new(f)))
|
||||
let args = [TypeId::of::<A>(), TypeId::of::<B>()];
|
||||
self.set_fn(name.into(), Public, &args, CF::from_method(Box::new(f)))
|
||||
}
|
||||
|
||||
/// Set a Rust function taking three parameters into the module, returning a hash key.
|
||||
@ -467,8 +455,8 @@ impl Module {
|
||||
|
||||
func(a, b, c).map(Dynamic::from)
|
||||
};
|
||||
let arg_types = [TypeId::of::<A>(), TypeId::of::<B>(), TypeId::of::<C>()];
|
||||
self.set_fn(name.into(), Public, &arg_types, Pure(Box::new(f)))
|
||||
let args = [TypeId::of::<A>(), TypeId::of::<B>(), TypeId::of::<C>()];
|
||||
self.set_fn(name.into(), Public, &args, CF::from_pure(Box::new(f)))
|
||||
}
|
||||
|
||||
/// Set a Rust function taking three parameters (the first one mutable) into the module,
|
||||
@ -506,8 +494,8 @@ impl Module {
|
||||
|
||||
func(a, b, c).map(Dynamic::from)
|
||||
};
|
||||
let arg_types = [TypeId::of::<A>(), TypeId::of::<B>(), TypeId::of::<C>()];
|
||||
self.set_fn(name.into(), Public, &arg_types, Method(Box::new(f)))
|
||||
let args = [TypeId::of::<A>(), TypeId::of::<B>(), TypeId::of::<C>()];
|
||||
self.set_fn(name.into(), Public, &args, CF::from_method(Box::new(f)))
|
||||
}
|
||||
|
||||
/// Get a Rust function.
|
||||
@ -524,8 +512,8 @@ impl Module {
|
||||
/// let hash = module.set_fn_1("calc", |x: i64| Ok(x + 1));
|
||||
/// assert!(module.get_fn(hash).is_some());
|
||||
/// ```
|
||||
pub fn get_fn(&self, hash_fn: u64) -> Option<&CallableFunction> {
|
||||
self.functions.get(&hash_fn).map(|(_, _, _, v)| v.as_ref())
|
||||
pub fn get_fn(&self, hash_fn: u64) -> Option<&CF> {
|
||||
self.functions.get(&hash_fn).map(|(_, _, _, v)| v)
|
||||
}
|
||||
|
||||
/// Get a modules-qualified function.
|
||||
@ -536,16 +524,13 @@ impl Module {
|
||||
&mut self,
|
||||
name: &str,
|
||||
hash_fn_native: u64,
|
||||
) -> Result<&CallableFunction, Box<EvalAltResult>> {
|
||||
self.all_functions
|
||||
.get(&hash_fn_native)
|
||||
.map(|f| f.as_ref())
|
||||
.ok_or_else(|| {
|
||||
Box::new(EvalAltResult::ErrorFunctionNotFound(
|
||||
name.to_string(),
|
||||
Position::none(),
|
||||
))
|
||||
})
|
||||
) -> Result<&CF, Box<EvalAltResult>> {
|
||||
self.all_functions.get(&hash_fn_native).ok_or_else(|| {
|
||||
Box::new(EvalAltResult::ErrorFunctionNotFound(
|
||||
name.to_string(),
|
||||
Position::none(),
|
||||
))
|
||||
})
|
||||
}
|
||||
|
||||
/// Create a new `Module` by evaluating an `AST`.
|
||||
@ -606,7 +591,7 @@ impl Module {
|
||||
module: &'a Module,
|
||||
qualifiers: &mut Vec<&'a str>,
|
||||
variables: &mut Vec<(u64, Dynamic)>,
|
||||
functions: &mut Vec<(u64, SharedFunction)>,
|
||||
functions: &mut Vec<(u64, CF)>,
|
||||
) {
|
||||
for (name, m) in &module.modules {
|
||||
// Index all the sub-modules first.
|
||||
@ -655,7 +640,7 @@ impl Module {
|
||||
fn_def.params.len(),
|
||||
empty(),
|
||||
);
|
||||
functions.push((hash_fn_def, CallableFunction::Script(fn_def.clone()).into()));
|
||||
functions.push((hash_fn_def, CF::Script(fn_def.clone()).into()));
|
||||
}
|
||||
}
|
||||
|
||||
@ -675,16 +660,11 @@ impl Module {
|
||||
|
||||
/// Set a type iterator into the module.
|
||||
pub fn set_iter(&mut self, typ: TypeId, func: Box<IteratorFn>) {
|
||||
#[cfg(not(feature = "sync"))]
|
||||
self.type_iterators
|
||||
.insert(typ, Rc::new(CallableFunction::Iterator(func)));
|
||||
#[cfg(feature = "sync")]
|
||||
self.type_iterators
|
||||
.insert(typ, Arc::new(CallableFunction::Iterator(func)));
|
||||
self.type_iterators.insert(typ, func.into());
|
||||
}
|
||||
|
||||
/// Get the specified type iterator.
|
||||
pub fn get_iter(&self, id: TypeId) -> Option<&CallableFunction> {
|
||||
pub fn get_iter(&self, id: TypeId) -> Option<&IteratorFn> {
|
||||
self.type_iterators.get(&id).map(|v| v.as_ref())
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
//! Module containing all built-in _packages_ available to Rhai, plus facilities to define custom packages.
|
||||
|
||||
use crate::fn_native::CallableFunction;
|
||||
use crate::fn_native::{CallableFunction, IteratorFn};
|
||||
use crate::module::Module;
|
||||
use crate::utils::StaticVec;
|
||||
|
||||
@ -81,7 +81,7 @@ impl PackagesCollection {
|
||||
self.packages.iter().any(|p| p.contains_iter(id))
|
||||
}
|
||||
/// Get the specified TypeId iterator.
|
||||
pub fn get_iter(&self, id: TypeId) -> Option<&CallableFunction> {
|
||||
pub fn get_iter(&self, id: TypeId) -> Option<&IteratorFn> {
|
||||
self.packages
|
||||
.iter()
|
||||
.map(|p| p.get_iter(id))
|
||||
|
@ -25,9 +25,7 @@ use crate::stdlib::{
|
||||
iter::{empty, Peekable},
|
||||
num::NonZeroUsize,
|
||||
ops::{Add, Deref, DerefMut},
|
||||
rc::Rc,
|
||||
string::{String, ToString},
|
||||
sync::Arc,
|
||||
vec,
|
||||
vec::Vec,
|
||||
};
|
||||
@ -59,21 +57,14 @@ type PERR = ParseErrorType;
|
||||
pub struct AST(
|
||||
/// Global statements.
|
||||
Vec<Stmt>,
|
||||
/// Script-defined functions, wrapped in an `Arc` for shared access.
|
||||
#[cfg(feature = "sync")]
|
||||
Arc<FunctionsLib>,
|
||||
/// Script-defined functions, wrapped in an `Rc` for shared access.
|
||||
#[cfg(not(feature = "sync"))]
|
||||
Rc<FunctionsLib>,
|
||||
/// Script-defined functions.
|
||||
FunctionsLib,
|
||||
);
|
||||
|
||||
impl AST {
|
||||
/// Create a new `AST`.
|
||||
pub fn new(statements: Vec<Stmt>, fn_lib: FunctionsLib) -> Self {
|
||||
#[cfg(feature = "sync")]
|
||||
return Self(statements, Arc::new(fn_lib));
|
||||
#[cfg(not(feature = "sync"))]
|
||||
return Self(statements, Rc::new(fn_lib));
|
||||
Self(statements, fn_lib)
|
||||
}
|
||||
|
||||
/// Get the statements.
|
||||
@ -88,7 +79,7 @@ impl AST {
|
||||
|
||||
/// Get the script-defined functions.
|
||||
pub(crate) fn fn_lib(&self) -> &FunctionsLib {
|
||||
self.1.as_ref()
|
||||
&self.1
|
||||
}
|
||||
|
||||
/// Merge two `AST` into one. Both `AST`'s are untouched and a new, merged, version
|
||||
@ -147,20 +138,13 @@ impl AST {
|
||||
(true, true) => vec![],
|
||||
};
|
||||
|
||||
Self::new(ast, functions.merge(other.1.as_ref()))
|
||||
Self::new(ast, functions.merge(&other.1))
|
||||
}
|
||||
|
||||
/// Clear all function definitions in the `AST`.
|
||||
#[cfg(not(feature = "no_function"))]
|
||||
pub fn clear_functions(&mut self) {
|
||||
#[cfg(feature = "sync")]
|
||||
{
|
||||
self.1 = Arc::new(Default::default());
|
||||
}
|
||||
#[cfg(not(feature = "sync"))]
|
||||
{
|
||||
self.1 = Rc::new(Default::default());
|
||||
}
|
||||
self.1 = Default::default();
|
||||
}
|
||||
|
||||
/// Clear all statements in the `AST`, leaving only function definitions.
|
||||
@ -202,13 +186,6 @@ pub struct FnDef {
|
||||
pub pos: Position,
|
||||
}
|
||||
|
||||
/// A sharable script-defined function.
|
||||
#[cfg(feature = "sync")]
|
||||
pub type SharedFnDef = Arc<FnDef>;
|
||||
/// A sharable script-defined function.
|
||||
#[cfg(not(feature = "sync"))]
|
||||
pub type SharedFnDef = Rc<FnDef>;
|
||||
|
||||
/// `return`/`throw` statement.
|
||||
#[derive(Debug, Eq, PartialEq, Hash, Clone, Copy)]
|
||||
pub enum ReturnType {
|
||||
|
Loading…
Reference in New Issue
Block a user