Add gen_fn_siguatures API.
This commit is contained in:
@@ -100,7 +100,7 @@ impl fmt::Display for ScriptFnDef {
|
||||
.iter()
|
||||
.map(|s| s.as_str())
|
||||
.collect::<Vec<_>>()
|
||||
.join(",")
|
||||
.join(", ")
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@@ -95,24 +95,25 @@ impl Imports {
|
||||
self.0.as_mut().unwrap().truncate(size);
|
||||
}
|
||||
}
|
||||
/// Get an iterator to this stack of imported modules.
|
||||
/// Get an iterator to this stack of imported modules in reverse order.
|
||||
#[allow(dead_code)]
|
||||
pub fn iter(&self) -> impl Iterator<Item = (&str, Shared<Module>)> {
|
||||
self.0.iter().flat_map(|lib| {
|
||||
lib.iter()
|
||||
.rev()
|
||||
.map(|(name, module)| (name.as_str(), module.clone()))
|
||||
})
|
||||
}
|
||||
/// Get an iterator to this stack of imported modules.
|
||||
/// Get an iterator to this stack of imported modules in reverse order.
|
||||
#[allow(dead_code)]
|
||||
pub(crate) fn iter_raw<'a>(
|
||||
&'a self,
|
||||
) -> impl Iterator<Item = (ImmutableString, Shared<Module>)> + 'a {
|
||||
self.0.iter().flat_map(|lib| lib.iter().cloned())
|
||||
self.0.iter().flat_map(|lib| lib.iter().rev().cloned())
|
||||
}
|
||||
/// Get a consuming iterator to this stack of imported modules.
|
||||
/// Get a consuming iterator to this stack of imported modules in reverse order.
|
||||
pub fn into_iter(self) -> impl Iterator<Item = (ImmutableString, Shared<Module>)> {
|
||||
self.0.into_iter().flat_map(|lib| lib.into_iter())
|
||||
self.0.into_iter().flat_map(|lib| lib.into_iter().rev())
|
||||
}
|
||||
/// Add a stream of imported modules.
|
||||
pub fn extend(&mut self, stream: impl Iterator<Item = (ImmutableString, Shared<Module>)>) {
|
||||
|
@@ -1515,7 +1515,7 @@ impl Engine {
|
||||
.into()
|
||||
});
|
||||
}
|
||||
/// 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.
|
||||
///
|
||||
/// ## WARNING
|
||||
@@ -1578,7 +1578,7 @@ impl Engine {
|
||||
|
||||
self.call_fn_dynamic_raw(scope, &[lib.as_ref()], name, &mut this_ptr, args.as_mut())
|
||||
}
|
||||
/// Call a script function defined in an [`AST`] with multiple `Dynamic` arguments.
|
||||
/// Call a script function defined in an [`AST`] with multiple [`Dynamic`] arguments.
|
||||
///
|
||||
/// ## WARNING
|
||||
///
|
||||
@@ -1646,6 +1646,27 @@ impl Engine {
|
||||
let stmt = crate::stdlib::mem::take(ast.statements_mut());
|
||||
crate::optimize::optimize_into_ast(self, scope, stmt, lib, optimization_level)
|
||||
}
|
||||
/// Generate a list of all registered functions.
|
||||
///
|
||||
/// The ordering is:
|
||||
/// 1) Functions registered into the global namespace
|
||||
/// 2) Functions in registered sub-modules
|
||||
/// 3) Functions in packages
|
||||
pub fn gen_fn_signatures(&self, include_packages: bool) -> Vec<String> {
|
||||
let mut signatures: Vec<_> = Default::default();
|
||||
|
||||
signatures.extend(self.global_namespace.gen_fn_signatures());
|
||||
|
||||
self.global_sub_modules.iter().for_each(|(name, m)| {
|
||||
signatures.extend(m.gen_fn_signatures().map(|f| format!("{}::{}", name, f)))
|
||||
});
|
||||
|
||||
if include_packages {
|
||||
signatures.extend(self.packages.gen_fn_signatures());
|
||||
}
|
||||
|
||||
signatures
|
||||
}
|
||||
/// Provide a callback that will be invoked before each variable access.
|
||||
///
|
||||
/// ## Return Value of Callback
|
||||
|
@@ -187,7 +187,7 @@ macro_rules! def_register {
|
||||
{
|
||||
#[inline]
|
||||
fn register_fn(&mut self, name: &str, f: FN) -> &mut Self {
|
||||
self.global_namespace.set_fn(name, FnNamespace::Global, FnAccess::Public,
|
||||
self.global_namespace.set_fn(name, FnNamespace::Global, FnAccess::Public, None,
|
||||
&[$(map_type_id::<$par>()),*],
|
||||
CallableFunction::$abi(make_func!(f : map_dynamic ; $($par => $let => $clone => $arg),*))
|
||||
);
|
||||
@@ -202,7 +202,7 @@ macro_rules! def_register {
|
||||
{
|
||||
#[inline]
|
||||
fn register_result_fn(&mut self, name: &str, f: FN) -> &mut Self {
|
||||
self.global_namespace.set_fn(name, FnNamespace::Global, FnAccess::Public,
|
||||
self.global_namespace.set_fn(name, FnNamespace::Global, FnAccess::Public, None,
|
||||
&[$(map_type_id::<$par>()),*],
|
||||
CallableFunction::$abi(make_func!(f : map_result ; $($par => $let => $clone => $arg),*))
|
||||
);
|
||||
|
@@ -79,7 +79,31 @@ pub struct FuncInfo {
|
||||
/// Number of parameters.
|
||||
pub params: usize,
|
||||
/// Parameter types (if applicable).
|
||||
pub types: Option<StaticVec<TypeId>>,
|
||||
pub param_types: Option<StaticVec<TypeId>>,
|
||||
/// Parameter names (if available).
|
||||
pub param_names: Option<StaticVec<ImmutableString>>,
|
||||
}
|
||||
|
||||
impl FuncInfo {
|
||||
/// Generate a signature of the function.
|
||||
pub fn gen_signature(&self) -> String {
|
||||
let mut sig = format!("{}(", self.name);
|
||||
|
||||
if let Some(ref names) = self.param_names {
|
||||
let params: Vec<_> = names.iter().map(ImmutableString::to_string).collect();
|
||||
sig.push_str(¶ms.join(", "));
|
||||
} else {
|
||||
for x in 0..self.params {
|
||||
sig.push_str("_");
|
||||
if x < self.params - 1 {
|
||||
sig.push_str(", ");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sig.push_str(")");
|
||||
sig
|
||||
}
|
||||
}
|
||||
|
||||
/// A module which may contain variables, sub-modules, external Rust functions,
|
||||
@@ -230,6 +254,14 @@ impl Module {
|
||||
self.indexed
|
||||
}
|
||||
|
||||
/// Generate signatures for all the functions in the module.
|
||||
pub fn gen_fn_signatures<'a>(&'a self) -> impl Iterator<Item = String> + 'a {
|
||||
self.functions
|
||||
.values()
|
||||
.filter(|FuncInfo { access, .. }| !access.is_private())
|
||||
.map(FuncInfo::gen_signature)
|
||||
}
|
||||
|
||||
/// Does a variable exist in the module?
|
||||
///
|
||||
/// # Example
|
||||
@@ -329,7 +361,8 @@ impl Module {
|
||||
namespace: FnNamespace::Internal,
|
||||
access: fn_def.access,
|
||||
params: num_params,
|
||||
types: None,
|
||||
param_types: None,
|
||||
param_names: Some(fn_def.params.clone()),
|
||||
func: fn_def.into(),
|
||||
},
|
||||
);
|
||||
@@ -450,6 +483,17 @@ impl Module {
|
||||
}
|
||||
}
|
||||
|
||||
/// Update the parameter names and types in a registered function.
|
||||
///
|
||||
/// The [`u64`] hash is calculated either by the function [`crate::calc_native_fn_hash`] or
|
||||
/// the function [`crate::calc_script_fn_hash`].
|
||||
pub fn update_fn_param_names(&mut self, hash_fn: u64, arg_names: &[&str]) -> &mut Self {
|
||||
if let Some(f) = self.functions.get_mut(&hash_fn) {
|
||||
f.param_names = Some(arg_names.iter().map(|&n| n.into()).collect());
|
||||
}
|
||||
self
|
||||
}
|
||||
|
||||
/// 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.
|
||||
@@ -462,6 +506,7 @@ impl Module {
|
||||
name: impl Into<String>,
|
||||
namespace: FnNamespace,
|
||||
access: FnAccess,
|
||||
arg_names: Option<&[&str]>,
|
||||
arg_types: &[TypeId],
|
||||
func: CallableFunction,
|
||||
) -> u64 {
|
||||
@@ -488,7 +533,8 @@ impl Module {
|
||||
namespace,
|
||||
access,
|
||||
params: params.len(),
|
||||
types: Some(params),
|
||||
param_types: Some(params),
|
||||
param_names: arg_names.map(|p| p.iter().map(|&v| v.into()).collect()),
|
||||
func: func.into(),
|
||||
},
|
||||
);
|
||||
@@ -576,6 +622,7 @@ impl Module {
|
||||
name,
|
||||
namespace,
|
||||
access,
|
||||
None,
|
||||
arg_types,
|
||||
CallableFunction::from_method(Box::new(f)),
|
||||
)
|
||||
@@ -606,6 +653,7 @@ impl Module {
|
||||
name,
|
||||
FnNamespace::Internal,
|
||||
FnAccess::Public,
|
||||
None,
|
||||
&arg_types,
|
||||
CallableFunction::from_pure(Box::new(f)),
|
||||
)
|
||||
@@ -638,6 +686,7 @@ impl Module {
|
||||
name,
|
||||
FnNamespace::Internal,
|
||||
FnAccess::Public,
|
||||
None,
|
||||
&arg_types,
|
||||
CallableFunction::from_pure(Box::new(f)),
|
||||
)
|
||||
@@ -673,6 +722,7 @@ impl Module {
|
||||
name,
|
||||
namespace,
|
||||
FnAccess::Public,
|
||||
None,
|
||||
&arg_types,
|
||||
CallableFunction::from_method(Box::new(f)),
|
||||
)
|
||||
@@ -738,6 +788,7 @@ impl Module {
|
||||
name,
|
||||
FnNamespace::Internal,
|
||||
FnAccess::Public,
|
||||
None,
|
||||
&arg_types,
|
||||
CallableFunction::from_pure(Box::new(f)),
|
||||
)
|
||||
@@ -780,6 +831,7 @@ impl Module {
|
||||
name,
|
||||
namespace,
|
||||
FnAccess::Public,
|
||||
None,
|
||||
&arg_types,
|
||||
CallableFunction::from_method(Box::new(f)),
|
||||
)
|
||||
@@ -900,6 +952,7 @@ impl Module {
|
||||
name,
|
||||
FnNamespace::Internal,
|
||||
FnAccess::Public,
|
||||
None,
|
||||
&arg_types,
|
||||
CallableFunction::from_pure(Box::new(f)),
|
||||
)
|
||||
@@ -948,6 +1001,7 @@ impl Module {
|
||||
name,
|
||||
namespace,
|
||||
FnAccess::Public,
|
||||
None,
|
||||
&arg_types,
|
||||
CallableFunction::from_method(Box::new(f)),
|
||||
)
|
||||
@@ -1008,6 +1062,7 @@ impl Module {
|
||||
crate::engine::FN_IDX_SET,
|
||||
FnNamespace::Internal,
|
||||
FnAccess::Public,
|
||||
None,
|
||||
&arg_types,
|
||||
CallableFunction::from_method(Box::new(f)),
|
||||
)
|
||||
@@ -1100,6 +1155,7 @@ impl Module {
|
||||
name,
|
||||
FnNamespace::Internal,
|
||||
FnAccess::Public,
|
||||
None,
|
||||
&arg_types,
|
||||
CallableFunction::from_pure(Box::new(f)),
|
||||
)
|
||||
@@ -1155,6 +1211,7 @@ impl Module {
|
||||
name,
|
||||
namespace,
|
||||
FnAccess::Public,
|
||||
None,
|
||||
&arg_types,
|
||||
CallableFunction::from_method(Box::new(f)),
|
||||
)
|
||||
@@ -1569,7 +1626,7 @@ impl Module {
|
||||
name,
|
||||
namespace,
|
||||
params,
|
||||
types,
|
||||
param_types: types,
|
||||
func,
|
||||
..
|
||||
},
|
||||
|
@@ -48,7 +48,8 @@ macro_rules! reg_range {
|
||||
($lib:expr, $x:expr, $( $y:ty ),*) => (
|
||||
$(
|
||||
$lib.set_iterator::<Range<$y>>();
|
||||
$lib.set_fn_2($x, get_range::<$y>);
|
||||
let hash = $lib.set_fn_2($x, get_range::<$y>);
|
||||
$lib.update_fn_param_names(hash, &[concat!("from: ", stringify!($y)), concat!("to: ", stringify!($y))]);
|
||||
)*
|
||||
)
|
||||
}
|
||||
@@ -59,14 +60,16 @@ macro_rules! reg_step {
|
||||
($lib:expr, $x:expr, $( $y:ty ),*) => (
|
||||
$(
|
||||
$lib.set_iterator::<StepRange<$y>>();
|
||||
$lib.set_fn_3($x, get_step_range::<$y>);
|
||||
let hash = $lib.set_fn_3($x, get_step_range::<$y>);
|
||||
$lib.update_fn_param_names(hash, &[concat!("from: ", stringify!($y)), concat!("to: ", stringify!($y)), concat!("step: ", stringify!($y))]);
|
||||
)*
|
||||
)
|
||||
}
|
||||
|
||||
def_package!(crate:BasicIteratorPackage:"Basic range iterators.", lib, {
|
||||
lib.set_iterator::<Range<INT>>();
|
||||
lib.set_fn_2("range", get_range::<INT>);
|
||||
let hash = lib.set_fn_2("range", get_range::<INT>);
|
||||
lib.update_fn_param_names(hash, &["from: INT", "to: INT"]);
|
||||
|
||||
#[cfg(not(feature = "only_i32"))]
|
||||
#[cfg(not(feature = "only_i64"))]
|
||||
@@ -79,7 +82,8 @@ def_package!(crate:BasicIteratorPackage:"Basic range iterators.", lib, {
|
||||
}
|
||||
|
||||
lib.set_iterator::<StepRange<INT>>();
|
||||
lib.set_fn_3("range", get_step_range::<INT>);
|
||||
let hash = lib.set_fn_3("range", get_step_range::<INT>);
|
||||
lib.update_fn_param_names(hash, &["from: INT", "to: INT", "step: INT"]);
|
||||
|
||||
#[cfg(not(feature = "only_i32"))]
|
||||
#[cfg(not(feature = "only_i64"))]
|
||||
|
@@ -87,6 +87,15 @@ impl PackagesCollection {
|
||||
.as_ref()
|
||||
.and_then(|x| x.iter().find_map(|p| p.get_iter(id)))
|
||||
}
|
||||
/// Get an iterator over all the packages in the [`PackagesCollection`].
|
||||
pub(crate) fn iter(&self) -> impl Iterator<Item = &PackageLibrary> {
|
||||
self.0.iter().flat_map(|p| p.iter())
|
||||
}
|
||||
|
||||
/// Generate signatures for all the functions in the [`PackagesCollection`].
|
||||
pub fn gen_fn_signatures<'a>(&'a self) -> impl Iterator<Item = String> + 'a {
|
||||
self.iter().flat_map(|m| m.gen_fn_signatures())
|
||||
}
|
||||
}
|
||||
|
||||
/// Macro that makes it easy to define a _package_ (which is basically a shared module)
|
||||
|
@@ -33,6 +33,9 @@ pub trait PluginFunction {
|
||||
/// Convert a plugin function into a boxed trait object.
|
||||
fn clone_boxed(&self) -> Box<dyn PluginFunction>;
|
||||
|
||||
/// Return a boxed slice of the names of the function's parameters.
|
||||
fn input_names(&self) -> Box<[&'static str]>;
|
||||
|
||||
/// Return a boxed slice of type ID's of the function's parameters.
|
||||
fn input_types(&self) -> Box<[TypeId]>;
|
||||
}
|
||||
|
17
src/token.rs
17
src/token.rs
@@ -2,7 +2,7 @@
|
||||
|
||||
use crate::engine::{
|
||||
KEYWORD_DEBUG, KEYWORD_EVAL, KEYWORD_FN_PTR, KEYWORD_FN_PTR_CALL, KEYWORD_FN_PTR_CURRY,
|
||||
KEYWORD_IS_DEF_FN, KEYWORD_IS_DEF_VAR, KEYWORD_PRINT, KEYWORD_THIS, KEYWORD_TYPE_OF,
|
||||
KEYWORD_PRINT, KEYWORD_THIS, KEYWORD_TYPE_OF,
|
||||
};
|
||||
use crate::stdlib::{
|
||||
borrow::Cow,
|
||||
@@ -538,11 +538,7 @@ impl Token {
|
||||
| "async" | "await" | "yield" => Reserved(syntax.into()),
|
||||
|
||||
KEYWORD_PRINT | KEYWORD_DEBUG | KEYWORD_TYPE_OF | KEYWORD_EVAL | KEYWORD_FN_PTR
|
||||
| KEYWORD_FN_PTR_CALL | KEYWORD_FN_PTR_CURRY | KEYWORD_IS_DEF_VAR
|
||||
| KEYWORD_IS_DEF_FN | KEYWORD_THIS => Reserved(syntax.into()),
|
||||
|
||||
#[cfg(not(feature = "no_closure"))]
|
||||
crate::engine::KEYWORD_IS_SHARED => Reserved(syntax.into()),
|
||||
| KEYWORD_FN_PTR_CALL | KEYWORD_FN_PTR_CURRY | KEYWORD_THIS => Reserved(syntax.into()),
|
||||
|
||||
_ => return None,
|
||||
})
|
||||
@@ -1513,12 +1509,8 @@ fn get_identifier(
|
||||
#[inline(always)]
|
||||
pub fn is_keyword_function(name: &str) -> bool {
|
||||
match name {
|
||||
#[cfg(not(feature = "no_closure"))]
|
||||
crate::engine::KEYWORD_IS_SHARED => true,
|
||||
KEYWORD_PRINT | KEYWORD_DEBUG | KEYWORD_TYPE_OF | KEYWORD_EVAL | KEYWORD_FN_PTR
|
||||
| KEYWORD_FN_PTR_CALL | KEYWORD_FN_PTR_CURRY | KEYWORD_IS_DEF_VAR | KEYWORD_IS_DEF_FN => {
|
||||
true
|
||||
}
|
||||
| KEYWORD_FN_PTR_CALL | KEYWORD_FN_PTR_CURRY => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
@@ -1528,8 +1520,7 @@ pub fn is_keyword_function(name: &str) -> bool {
|
||||
#[inline(always)]
|
||||
pub fn can_override_keyword(name: &str) -> bool {
|
||||
match name {
|
||||
KEYWORD_PRINT | KEYWORD_DEBUG | KEYWORD_TYPE_OF | KEYWORD_EVAL | KEYWORD_FN_PTR
|
||||
| KEYWORD_IS_DEF_VAR | KEYWORD_IS_DEF_FN => true,
|
||||
KEYWORD_PRINT | KEYWORD_DEBUG | KEYWORD_TYPE_OF | KEYWORD_EVAL | KEYWORD_FN_PTR => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user