Use HashMap for externals.

This commit is contained in:
Stephen Chung 2020-07-29 23:34:48 +08:00
parent 8299adf95c
commit 721c578407

View File

@ -25,7 +25,7 @@ use crate::stdlib::{
borrow::Cow, borrow::Cow,
boxed::Box, boxed::Box,
char, char,
collections::{HashMap, HashSet}, collections::HashMap,
fmt, format, fmt, format,
hash::{Hash, Hasher}, hash::{Hash, Hasher},
iter::empty, iter::empty,
@ -410,7 +410,7 @@ struct ParseState<'e> {
stack: Vec<(String, ScopeEntryType)>, stack: Vec<(String, ScopeEntryType)>,
/// Tracks a list of external variables (variables that are not explicitly declared in the scope). /// Tracks a list of external variables (variables that are not explicitly declared in the scope).
#[cfg(not(feature = "no_capture"))] #[cfg(not(feature = "no_capture"))]
externals: HashSet<(String, Position)>, externals: HashMap<String, Position>,
/// Encapsulates a local stack with variable names to simulate an actual runtime scope. /// Encapsulates a local stack with variable names to simulate an actual runtime scope.
modules: Vec<String>, modules: Vec<String>,
/// Maximum levels of expression nesting. /// Maximum levels of expression nesting.
@ -458,8 +458,8 @@ impl<'e> ParseState<'e> {
.and_then(|(i, _)| NonZeroUsize::new(i + 1)); .and_then(|(i, _)| NonZeroUsize::new(i + 1));
#[cfg(not(feature = "no_capture"))] #[cfg(not(feature = "no_capture"))]
if index.is_none() { if index.is_none() && !self.externals.contains_key(name) {
self.externals.insert((name.to_string(), pos)); self.externals.insert(name.to_string(), pos);
} }
index index
@ -3157,16 +3157,17 @@ fn parse_anon_fn(
let body = parse_stmt(input, state, lib, settings.level_up()) let body = parse_stmt(input, state, lib, settings.level_up())
.map(|stmt| stmt.unwrap_or_else(|| Stmt::Noop(pos)))?; .map(|stmt| stmt.unwrap_or_else(|| Stmt::Noop(pos)))?;
let mut static_params: StaticVec<_> = Default::default(); #[cfg(feature = "no_capture")]
let params: StaticVec<_> = params.into_iter().map(|(v, _)| v).collect();
// Add parameters that are auto-curried
#[cfg(not(feature = "no_capture"))] #[cfg(not(feature = "no_capture"))]
state.externals.iter().for_each(|(closure, _)| { let params: StaticVec<_> = state
static_params.push(closure.clone()); .externals
}); .keys()
.cloned()
for param in params.into_iter() { .chain(params.into_iter().map(|(v, _)| v))
static_params.push(param.0); .collect();
}
// Calculate hash // Calculate hash
#[cfg(feature = "no_std")] #[cfg(feature = "no_std")]
@ -3174,8 +3175,8 @@ fn parse_anon_fn(
#[cfg(not(feature = "no_std"))] #[cfg(not(feature = "no_std"))]
let mut s = DefaultHasher::new(); let mut s = DefaultHasher::new();
s.write_usize(static_params.len()); s.write_usize(params.len());
static_params.iter().for_each(|a| a.hash(&mut s)); params.iter().for_each(|a| a.hash(&mut s));
body.hash(&mut s); body.hash(&mut s);
let hash = s.finish(); let hash = s.finish();
@ -3185,7 +3186,7 @@ fn parse_anon_fn(
let script = ScriptFnDef { let script = ScriptFnDef {
name: fn_name.clone(), name: fn_name.clone(),
access: FnAccess::Public, access: FnAccess::Public,
params: static_params, params,
body, body,
pos: settings.pos, pos: settings.pos,
}; };