Streamline code.

This commit is contained in:
Stephen Chung 2021-03-24 10:02:50 +08:00
parent 6d1700728a
commit 3d0d5d1708
10 changed files with 99 additions and 105 deletions

View File

@ -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();

View File

@ -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 {

View File

@ -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);

View File

@ -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

View File

@ -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.
/// ///

View File

@ -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));
} }
} }

View File

@ -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());
} }

View File

@ -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.

View File

@ -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 {

View File

@ -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