Streamline code.
This commit is contained in:
parent
6d1700728a
commit
3d0d5d1708
@ -300,29 +300,28 @@ impl Parse for ExportedFn {
|
|||||||
let visibility = fn_all.vis;
|
let visibility = fn_all.vis;
|
||||||
|
|
||||||
// Determine if the function requires a call context
|
// Determine if the function requires a call context
|
||||||
if let Some(first_arg) = fn_all.sig.inputs.first() {
|
match fn_all.sig.inputs.first() {
|
||||||
if let syn::FnArg::Typed(syn::PatType { ref ty, .. }) = first_arg {
|
Some(syn::FnArg::Typed(syn::PatType { ref ty, .. })) => {
|
||||||
match flatten_type_groups(ty.as_ref()) {
|
match flatten_type_groups(ty.as_ref()) {
|
||||||
syn::Type::Path(p)
|
syn::Type::Path(p)
|
||||||
if p.path == context_type_path1 || p.path == context_type_path2 =>
|
if p.path == context_type_path1 || p.path == context_type_path2 =>
|
||||||
{
|
{
|
||||||
pass_context = true;
|
pass_context = true;
|
||||||
}
|
}
|
||||||
_ => (),
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
let skip_slots = if pass_context { 1 } else { 0 };
|
let skip_slots = if pass_context { 1 } else { 0 };
|
||||||
|
|
||||||
// Determine whether function generates a special calling convention for a mutable receiver.
|
// Determine whether function generates a special calling convention for a mutable receiver.
|
||||||
let mut_receiver = {
|
let mut_receiver = match fn_all.sig.inputs.iter().skip(skip_slots).next() {
|
||||||
if let Some(first_arg) = fn_all.sig.inputs.iter().skip(skip_slots).next() {
|
Some(syn::FnArg::Receiver(syn::Receiver {
|
||||||
match first_arg {
|
|
||||||
syn::FnArg::Receiver(syn::Receiver {
|
|
||||||
reference: Some(_), ..
|
reference: Some(_), ..
|
||||||
}) => true,
|
})) => true,
|
||||||
syn::FnArg::Typed(syn::PatType { ref ty, .. }) => {
|
Some(syn::FnArg::Typed(syn::PatType { ref ty, .. })) => {
|
||||||
match flatten_type_groups(ty.as_ref()) {
|
match flatten_type_groups(ty.as_ref()) {
|
||||||
syn::Type::Reference(syn::TypeReference {
|
syn::Type::Reference(syn::TypeReference {
|
||||||
mutability: Some(_),
|
mutability: Some(_),
|
||||||
@ -345,10 +344,6 @@ impl Parse for ExportedFn {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
|
||||||
} else {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// All arguments after the first must be moved except for &str.
|
// All arguments after the first must be moved except for &str.
|
||||||
@ -381,7 +376,8 @@ impl Parse for ExportedFn {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check return type.
|
// Check return type.
|
||||||
if let syn::ReturnType::Type(_, ref ret_type) = fn_all.sig.output {
|
match fn_all.sig.output {
|
||||||
|
syn::ReturnType::Type(_, ref ret_type) => {
|
||||||
match flatten_type_groups(ret_type.as_ref()) {
|
match flatten_type_groups(ret_type.as_ref()) {
|
||||||
syn::Type::Ptr(_) => {
|
syn::Type::Ptr(_) => {
|
||||||
return Err(syn::Error::new(
|
return Err(syn::Error::new(
|
||||||
@ -398,6 +394,8 @@ impl Parse for ExportedFn {
|
|||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
Ok(ExportedFn {
|
Ok(ExportedFn {
|
||||||
entire_span,
|
entire_span,
|
||||||
signature: fn_all.sig,
|
signature: fn_all.sig,
|
||||||
@ -494,10 +492,9 @@ impl ExportedFn {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn return_type(&self) -> Option<&syn::Type> {
|
pub fn return_type(&self) -> Option<&syn::Type> {
|
||||||
if let syn::ReturnType::Type(_, ref ret_type) = self.signature.output {
|
match self.signature.output {
|
||||||
Some(flatten_type_groups(ret_type))
|
syn::ReturnType::Type(_, ref ret_type) => Some(flatten_type_groups(ret_type)),
|
||||||
} else {
|
_ => None,
|
||||||
None
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -622,16 +619,12 @@ impl ExportedFn {
|
|||||||
let arguments: Vec<syn::Ident> = dynamic_signature
|
let arguments: Vec<syn::Ident> = dynamic_signature
|
||||||
.inputs
|
.inputs
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|fn_arg| {
|
.filter_map(|fn_arg| match fn_arg {
|
||||||
if let syn::FnArg::Typed(syn::PatType { ref pat, .. }) = fn_arg {
|
syn::FnArg::Typed(syn::PatType { ref pat, .. }) => match pat.as_ref() {
|
||||||
if let syn::Pat::Ident(ref ident) = pat.as_ref() {
|
syn::Pat::Ident(ref ident) => Some(ident.ident.clone()),
|
||||||
Some(ident.ident.clone())
|
_ => None,
|
||||||
} else {
|
},
|
||||||
None
|
_ => None,
|
||||||
}
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
|
@ -156,8 +156,11 @@ impl Parse for Module {
|
|||||||
}) => {
|
}) => {
|
||||||
// #[cfg] attributes are not allowed on const declarations
|
// #[cfg] attributes are not allowed on const declarations
|
||||||
crate::attrs::deny_cfg_attr(&attrs)?;
|
crate::attrs::deny_cfg_attr(&attrs)?;
|
||||||
if let syn::Visibility::Public(_) = vis {
|
match vis {
|
||||||
consts.push((ident.to_string(), ty.clone(), expr.as_ref().clone()));
|
syn::Visibility::Public(_) => {
|
||||||
|
consts.push((ident.to_string(), ty.clone(), expr.as_ref().clone()))
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
@ -170,26 +173,23 @@ impl Parse for Module {
|
|||||||
sub_modules.reserve(content.len() - fns.len() - consts.len());
|
sub_modules.reserve(content.len() - fns.len() - consts.len());
|
||||||
let mut i = 0;
|
let mut i = 0;
|
||||||
while i < content.len() {
|
while i < content.len() {
|
||||||
if let syn::Item::Mod(_) = &content[i] {
|
match content[i] {
|
||||||
|
syn::Item::Mod(_) => {
|
||||||
let mut item_mod = match content.remove(i) {
|
let mut item_mod = match content.remove(i) {
|
||||||
syn::Item::Mod(m) => m,
|
syn::Item::Mod(m) => m,
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
};
|
};
|
||||||
let params: ExportedModParams = match crate::attrs::inner_item_attributes(
|
let params: ExportedModParams =
|
||||||
&mut item_mod.attrs,
|
crate::attrs::inner_item_attributes(&mut item_mod.attrs, "rhai_mod")?;
|
||||||
"rhai_mod",
|
let module = syn::parse2::<Module>(item_mod.to_token_stream()).and_then(
|
||||||
) {
|
|mut m| {
|
||||||
Ok(p) => p,
|
|
||||||
Err(e) => return Err(e),
|
|
||||||
};
|
|
||||||
let module =
|
|
||||||
syn::parse2::<Module>(item_mod.to_token_stream()).and_then(|mut m| {
|
|
||||||
m.set_params(params)?;
|
m.set_params(params)?;
|
||||||
Ok(m)
|
Ok(m)
|
||||||
})?;
|
},
|
||||||
|
)?;
|
||||||
sub_modules.push(module);
|
sub_modules.push(module);
|
||||||
} else {
|
}
|
||||||
i += 1;
|
_ => i += 1,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -1513,7 +1513,7 @@ impl FloatWrapper {
|
|||||||
#[derive(Debug, Clone, Hash)]
|
#[derive(Debug, Clone, Hash)]
|
||||||
pub enum Expr {
|
pub enum Expr {
|
||||||
/// Dynamic constant.
|
/// Dynamic constant.
|
||||||
/// Used to hold either an [`Array`] or [`Map`] literal for quick cloning.
|
/// Used to hold either an [`Array`] or [`Map`][crate::Map] literal for quick cloning.
|
||||||
/// All other primitive data types should use the appropriate variants for better speed.
|
/// All other primitive data types should use the appropriate variants for better speed.
|
||||||
DynamicConstant(Box<Dynamic>, Position),
|
DynamicConstant(Box<Dynamic>, Position),
|
||||||
/// Boolean constant.
|
/// Boolean constant.
|
||||||
@ -1855,7 +1855,7 @@ mod tests {
|
|||||||
assert_eq!(size_of::<Option<ast::Expr>>(), 16);
|
assert_eq!(size_of::<Option<ast::Expr>>(), 16);
|
||||||
assert_eq!(size_of::<ast::Stmt>(), 40);
|
assert_eq!(size_of::<ast::Stmt>(), 40);
|
||||||
assert_eq!(size_of::<Option<ast::Stmt>>(), 40);
|
assert_eq!(size_of::<Option<ast::Stmt>>(), 40);
|
||||||
assert_eq!(size_of::<FnPtr>(), 32);
|
assert_eq!(size_of::<FnPtr>(), 80);
|
||||||
assert_eq!(size_of::<Scope>(), 288);
|
assert_eq!(size_of::<Scope>(), 288);
|
||||||
assert_eq!(size_of::<LexError>(), 56);
|
assert_eq!(size_of::<LexError>(), 56);
|
||||||
assert_eq!(size_of::<ParseError>(), 16);
|
assert_eq!(size_of::<ParseError>(), 16);
|
||||||
|
@ -997,11 +997,11 @@ impl Engine {
|
|||||||
|
|
||||||
// Check if the variable is `this`
|
// Check if the variable is `this`
|
||||||
if name.as_str() == KEYWORD_THIS {
|
if name.as_str() == KEYWORD_THIS {
|
||||||
if let Some(val) = this_ptr {
|
return if let Some(val) = this_ptr {
|
||||||
return Ok(((*val).into(), *pos));
|
Ok(((*val).into(), *pos))
|
||||||
} else {
|
} else {
|
||||||
return EvalAltResult::ErrorUnboundThis(*pos).into();
|
EvalAltResult::ErrorUnboundThis(*pos).into()
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if it is directly indexed
|
// Check if it is directly indexed
|
||||||
|
@ -1232,7 +1232,7 @@ impl Engine {
|
|||||||
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)?))
|
||||||
}
|
}
|
||||||
/// Parse a JSON string into an [object map][`Map`].
|
/// Parse a JSON string into an [object map][`Map`].
|
||||||
/// This is a light-weight alternative to using, say, [`serde_json`][https://crates.io/crates/serde_json] to deserialize the JSON.
|
/// This is a light-weight alternative to using, say, [`serde_json`] to deserialize the JSON.
|
||||||
///
|
///
|
||||||
/// The JSON string must be an object hash. It cannot be a simple scalar value.
|
/// The JSON string must be an object hash. It cannot be a simple scalar value.
|
||||||
///
|
///
|
||||||
|
@ -26,7 +26,7 @@ pub trait FuncArgs {
|
|||||||
/// }
|
/// }
|
||||||
///
|
///
|
||||||
/// impl FuncArgs for Options {
|
/// impl FuncArgs for Options {
|
||||||
/// fn parse<C: Extend<Dynamic>>(self, container: &mut C) {
|
/// fn parse<CONTAINER: Extend<Dynamic>>(self, container: &mut CONTAINER) {
|
||||||
/// container.extend(std::iter::once(self.foo.into()));
|
/// container.extend(std::iter::once(self.foo.into()));
|
||||||
/// container.extend(std::iter::once(self.bar.into()));
|
/// container.extend(std::iter::once(self.bar.into()));
|
||||||
/// container.extend(std::iter::once(self.baz.into()));
|
/// container.extend(std::iter::once(self.baz.into()));
|
||||||
@ -51,11 +51,12 @@ pub trait FuncArgs {
|
|||||||
/// # Ok(())
|
/// # Ok(())
|
||||||
/// # }
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
fn parse<T: Extend<Dynamic>>(self, container: &mut T);
|
fn parse<CONTAINER: Extend<Dynamic>>(self, container: &mut CONTAINER);
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Variant + Clone> FuncArgs for Vec<T> {
|
impl<T: Variant + Clone> FuncArgs for Vec<T> {
|
||||||
fn parse<C: Extend<Dynamic>>(self, container: &mut C) {
|
#[inline(always)]
|
||||||
|
fn parse<CONTAINER: Extend<Dynamic>>(self, container: &mut CONTAINER) {
|
||||||
container.extend(self.into_iter().map(Variant::into_dynamic));
|
container.extend(self.into_iter().map(Variant::into_dynamic));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1132,13 +1132,10 @@ impl Engine {
|
|||||||
|
|
||||||
// Append the new curried arguments to the existing list.
|
// Append the new curried arguments to the existing list.
|
||||||
|
|
||||||
args_expr.iter().skip(1).try_for_each(
|
args_expr.iter().skip(1).try_for_each(|expr| {
|
||||||
|expr| -> Result<(), Box<EvalAltResult>> {
|
self.eval_expr(scope, mods, state, lib, this_ptr, expr, level)
|
||||||
fn_curry
|
.map(|value| fn_curry.push(value))
|
||||||
.push(self.eval_expr(scope, mods, state, lib, this_ptr, expr, level)?);
|
})?;
|
||||||
Ok(())
|
|
||||||
},
|
|
||||||
)?;
|
|
||||||
|
|
||||||
return Ok(FnPtr::new_unchecked(name, fn_curry).into());
|
return Ok(FnPtr::new_unchecked(name, fn_curry).into());
|
||||||
}
|
}
|
||||||
|
@ -10,12 +10,11 @@ use crate::stdlib::{
|
|||||||
iter::empty,
|
iter::empty,
|
||||||
mem,
|
mem,
|
||||||
string::String,
|
string::String,
|
||||||
vec::Vec,
|
|
||||||
};
|
};
|
||||||
use crate::token::is_valid_identifier;
|
use crate::token::is_valid_identifier;
|
||||||
use crate::{
|
use crate::{
|
||||||
calc_fn_hash, Dynamic, Engine, EvalAltResult, EvalContext, ImmutableString, Module, Position,
|
calc_fn_hash, Dynamic, Engine, EvalAltResult, EvalContext, ImmutableString, Module, Position,
|
||||||
RhaiResult,
|
RhaiResult, StaticVec,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Trait that maps to `Send + Sync` only under the `sync` feature.
|
/// Trait that maps to `Send + Sync` only under the `sync` feature.
|
||||||
@ -251,7 +250,7 @@ pub type FnCallArgs<'a> = [&'a mut Dynamic];
|
|||||||
/// A general function pointer, which may carry additional (i.e. curried) argument values
|
/// A general function pointer, which may carry additional (i.e. curried) argument values
|
||||||
/// to be passed onto a function during a call.
|
/// to be passed onto a function during a call.
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct FnPtr(ImmutableString, Vec<Dynamic>);
|
pub struct FnPtr(ImmutableString, StaticVec<Dynamic>);
|
||||||
|
|
||||||
impl FnPtr {
|
impl FnPtr {
|
||||||
/// Create a new function pointer.
|
/// Create a new function pointer.
|
||||||
@ -261,7 +260,10 @@ impl FnPtr {
|
|||||||
}
|
}
|
||||||
/// Create a new function pointer without checking its parameters.
|
/// Create a new function pointer without checking its parameters.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub(crate) fn new_unchecked(name: impl Into<ImmutableString>, curry: Vec<Dynamic>) -> Self {
|
pub(crate) fn new_unchecked(
|
||||||
|
name: impl Into<ImmutableString>,
|
||||||
|
curry: StaticVec<Dynamic>,
|
||||||
|
) -> Self {
|
||||||
Self(name.into(), curry)
|
Self(name.into(), curry)
|
||||||
}
|
}
|
||||||
/// Get the name of the function.
|
/// Get the name of the function.
|
||||||
@ -276,7 +278,7 @@ impl FnPtr {
|
|||||||
}
|
}
|
||||||
/// Get the underlying data of the function pointer.
|
/// Get the underlying data of the function pointer.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub(crate) fn take_data(self) -> (ImmutableString, Vec<Dynamic>) {
|
pub(crate) fn take_data(self) -> (ImmutableString, StaticVec<Dynamic>) {
|
||||||
(self.0, self.1)
|
(self.0, self.1)
|
||||||
}
|
}
|
||||||
/// Get the curried arguments.
|
/// Get the curried arguments.
|
||||||
|
@ -61,6 +61,8 @@ pub fn by_value<T: Variant + Clone>(data: &mut Dynamic) -> T {
|
|||||||
|
|
||||||
/// Trait to register custom Rust functions.
|
/// Trait to register custom Rust functions.
|
||||||
pub trait RegisterNativeFunction<Args, Result> {
|
pub trait RegisterNativeFunction<Args, Result> {
|
||||||
|
/// Convert this function into a [`CallableFunction`].
|
||||||
|
fn into_callable_function(self) -> CallableFunction;
|
||||||
/// Get the type ID's of this function's parameters.
|
/// Get the type ID's of this function's parameters.
|
||||||
fn param_types() -> Box<[TypeId]>;
|
fn param_types() -> Box<[TypeId]>;
|
||||||
/// Get the type names of this function's parameters.
|
/// Get the type names of this function's parameters.
|
||||||
@ -69,8 +71,6 @@ pub trait RegisterNativeFunction<Args, Result> {
|
|||||||
fn return_type() -> TypeId;
|
fn return_type() -> TypeId;
|
||||||
/// Get the type name of this function's return value.
|
/// Get the type name of this function's return value.
|
||||||
fn return_type_name() -> &'static str;
|
fn return_type_name() -> &'static str;
|
||||||
/// Convert this function into a [`CallableFunction`].
|
|
||||||
fn into_callable_function(self) -> CallableFunction;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! def_register {
|
macro_rules! def_register {
|
||||||
|
@ -71,6 +71,7 @@ impl<'a> IntoIterator for Scope<'a> {
|
|||||||
type Item = (Cow<'a, str>, Dynamic);
|
type Item = (Cow<'a, str>, Dynamic);
|
||||||
type IntoIter = Box<dyn Iterator<Item = Self::Item> + 'a>;
|
type IntoIter = Box<dyn Iterator<Item = Self::Item> + 'a>;
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
fn into_iter(self) -> Self::IntoIter {
|
fn into_iter(self) -> Self::IntoIter {
|
||||||
Box::new(
|
Box::new(
|
||||||
self.values
|
self.values
|
||||||
|
Loading…
Reference in New Issue
Block a user