Iterator reference parameters.

This commit is contained in:
Stephen Chung 2021-06-21 19:12:28 +08:00
parent 3b345acebf
commit 2342777a13
5 changed files with 33 additions and 64 deletions

View File

@ -1498,12 +1498,12 @@ impl fmt::Debug for FnCallHashes {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
if let Some(script) = self.script { if let Some(script) = self.script {
if script == self.native { if script == self.native {
write!(f, "({}=={})", script, self.native) fmt::Debug::fmt(&self.native, f)
} else { } else {
write!(f, "({}, {})", script, self.native) write!(f, "({}, {})", script, self.native)
} }
} else { } else {
write!(f, "{}", self.native) write!(f, "{} (native only)", self.native)
} }
} }
} }

View File

@ -95,7 +95,7 @@ impl Imports {
.iter() .iter()
.enumerate() .enumerate()
.rev() .rev()
.find_map(|(i, key)| if *key == name { Some(i) } else { None }) .find_map(|(i, key)| if key == name { Some(i) } else { None })
} }
/// Push an imported [modules][Module] onto the stack. /// Push an imported [modules][Module] onto the stack.
#[inline(always)] #[inline(always)]

View File

@ -142,7 +142,7 @@ impl Engine {
.map(|a| if a.is::<ImmutableString>() { .map(|a| if a.is::<ImmutableString>() {
"&str | ImmutableString | String" "&str | ImmutableString | String"
} else { } else {
self.map_type_name((*a).type_name()) self.map_type_name(a.type_name())
}) })
.collect::<StaticVec<_>>() .collect::<StaticVec<_>>()
.join(", ") .join(", ")
@ -171,8 +171,10 @@ impl Engine {
is_op_assignment: bool, is_op_assignment: bool,
) -> &'s Option<Box<FnResolutionCacheEntry>> { ) -> &'s Option<Box<FnResolutionCacheEntry>> {
let mut hash = args.as_ref().map_or(hash_script, |args| { let mut hash = args.as_ref().map_or(hash_script, |args| {
let hash_params = calc_fn_params_hash(args.iter().map(|a| a.type_id())); combine_hashes(
combine_hashes(hash_script, hash_params) hash_script,
calc_fn_params_hash(args.iter().map(|a| a.type_id())),
)
}); });
&*state &*state
@ -188,43 +190,17 @@ impl Engine {
let mut bitmask = 1usize; // Bitmask of which parameter to replace with `Dynamic` let mut bitmask = 1usize; // Bitmask of which parameter to replace with `Dynamic`
loop { loop {
let func = lib let func = lib.iter().find_map(|m| m.get_fn(hash).cloned().map(|func| FnResolutionCacheEntry {
.iter() func, source: m.id_raw().cloned()
.find_map(|m| { })).or_else(|| self.global_namespace.get_fn(hash).cloned().map(|func| FnResolutionCacheEntry {
m.get_fn(hash).cloned().map(|func| { func, source: None
let source = m.id_raw().cloned(); })).or_else(|| self.global_modules.iter().find_map(|m| m.get_fn(hash).cloned().map(|func| FnResolutionCacheEntry {
FnResolutionCacheEntry { func, source } func, source: m.id_raw().cloned()
}) }))).or_else(|| mods.get_fn(hash).map(|(func, source)| FnResolutionCacheEntry {
}) func: func.clone(), source: source.cloned()
.or_else(|| { })).or_else(|| self.global_sub_modules.values().find_map(|m| m.get_qualified_fn(hash).cloned().map(|func| FnResolutionCacheEntry {
self.global_namespace func, source: m.id_raw().cloned()
.get_fn(hash) })));
.cloned()
.map(|func| FnResolutionCacheEntry { func, source: None })
})
.or_else(|| {
self.global_modules.iter().find_map(|m| {
m.get_fn(hash).cloned().map(|func| {
let source = m.id_raw().cloned();
FnResolutionCacheEntry { func, source }
})
})
})
.or_else(|| {
mods.get_fn(hash).map(|(func, source)| {
let func = func.clone();
let source = source.cloned();
FnResolutionCacheEntry { func, source }
})
})
.or_else(|| {
self.global_sub_modules.values().find_map(|m| {
m.get_qualified_fn(hash).cloned().map(|func| {
let source = m.id_raw().cloned();
FnResolutionCacheEntry { func, source }
})
})
});
match func { match func {
// Specific version found // Specific version found
@ -239,23 +215,17 @@ impl Engine {
return args.and_then(|args| { return args.and_then(|args| {
if !is_op_assignment { if !is_op_assignment {
get_builtin_binary_op_fn(fn_name, &args[0], &args[1]).map(|f| { get_builtin_binary_op_fn(fn_name, &args[0], &args[1]).map(|f| {
let func = CallableFunction::from_method( FnResolutionCacheEntry { func: CallableFunction::from_method(
Box::new(f) as Box<FnAny> Box::new(f) as Box<FnAny>
); ), source: None }
FnResolutionCacheEntry { func, source: None }
}) })
} else { } else {
let (first, second) = args.split_first() let (first, second) = args.split_first()
.expect("never fails because an op-assignment must have two arguments"); .expect("never fails because an op-assignment must have two arguments");
get_builtin_op_assignment_fn(fn_name, *first, second[0]).map( get_builtin_op_assignment_fn(fn_name, *first, second[0]).map(|f| FnResolutionCacheEntry {
|f| { func: CallableFunction::from_method(Box::new(f) as Box<FnAny>), source: None
let func = CallableFunction::from_method( })
Box::new(f) as Box<FnAny>
);
FnResolutionCacheEntry { func, source: None }
},
)
} }
.map(Box::new) .map(Box::new)
}); });
@ -437,11 +407,10 @@ impl Engine {
} }
// Raise error // Raise error
_ => EvalAltResult::ErrorFunctionNotFound( _ => {
self.gen_call_signature(None, name, args.as_ref()), EvalAltResult::ErrorFunctionNotFound(self.gen_call_signature(None, name, args), pos)
pos, .into()
) }
.into(),
} }
} }
@ -1451,7 +1420,7 @@ impl Engine {
Some(f) => unreachable!("unknown function type: {:?}", f), Some(f) => unreachable!("unknown function type: {:?}", f),
None => EvalAltResult::ErrorFunctionNotFound( None => EvalAltResult::ErrorFunctionNotFound(
self.gen_call_signature(Some(namespace), fn_name, args.as_ref()), self.gen_call_signature(Some(namespace), fn_name, &args),
pos, pos,
) )
.into(), .into(),

View File

@ -191,7 +191,7 @@ impl<'e> ParseState<'e> {
.iter() .iter()
.rev() .rev()
.enumerate() .enumerate()
.find(|&(_, n)| *n == name) .find(|&(_, n)| n == name)
.and_then(|(i, _)| NonZeroUsize::new(i + 1)) .and_then(|(i, _)| NonZeroUsize::new(i + 1))
} }
@ -1070,8 +1070,8 @@ fn parse_primary(
let (expr, func) = parse_anon_fn(input, &mut new_state, lib, settings)?; let (expr, func) = parse_anon_fn(input, &mut new_state, lib, settings)?;
#[cfg(not(feature = "no_closure"))] #[cfg(not(feature = "no_closure"))]
new_state.external_vars.iter().for_each(|(closure, pos)| { new_state.external_vars.iter().for_each(|(closure, &pos)| {
state.access_var(closure, *pos); state.access_var(closure, pos);
}); });
let hash_script = calc_fn_hash(&func.name, func.params.len()); let hash_script = calc_fn_hash(&func.name, func.params.len());

View File

@ -448,7 +448,7 @@ impl<'a> Scope<'a> {
.1 .1
.as_mut() .as_mut()
.expect("never fails because the list is initialized"); .expect("never fails because the list is initialized");
if !list.iter().any(|a| &alias == a) { if !list.iter().any(|a| a == &alias) {
list.push(alias); list.push(alias);
} }
self self