Merge variables in Stmt::Share.
This commit is contained in:
parent
91415b9750
commit
d97f3f7ec4
@ -605,19 +605,16 @@ pub enum Stmt {
|
||||
/// Not available under `no_module`.
|
||||
#[cfg(not(feature = "no_module"))]
|
||||
Export(Box<(Ident, Ident)>, Position),
|
||||
/// Convert a variable to shared.
|
||||
/// Convert a list of variables to shared.
|
||||
///
|
||||
/// Not available under `no_closure`.
|
||||
///
|
||||
/// # Notes
|
||||
///
|
||||
/// This variant does not map to any language structure. It is currently only used only to
|
||||
/// convert a normal variable into a shared variable when the variable is _captured_ by a closure.
|
||||
/// convert normal variables into shared variables when they are _captured_ by a closure.
|
||||
#[cfg(not(feature = "no_closure"))]
|
||||
Share(
|
||||
Box<(crate::ImmutableString, Option<NonZeroUsize>)>,
|
||||
Position,
|
||||
),
|
||||
Share(Box<crate::FnArgsVec<(crate::ImmutableString, Option<NonZeroUsize>, Position)>>),
|
||||
}
|
||||
|
||||
impl Default for Stmt {
|
||||
@ -684,7 +681,7 @@ impl Stmt {
|
||||
Self::Export(.., pos) => *pos,
|
||||
|
||||
#[cfg(not(feature = "no_closure"))]
|
||||
Self::Share(.., pos) => *pos,
|
||||
Self::Share(x) => x[0].2,
|
||||
}
|
||||
}
|
||||
/// Override the [position][Position] of this statement.
|
||||
@ -716,7 +713,7 @@ impl Stmt {
|
||||
Self::Export(.., pos) => *pos = new_pos,
|
||||
|
||||
#[cfg(not(feature = "no_closure"))]
|
||||
Self::Share(.., pos) => *pos = new_pos,
|
||||
Self::Share(x) => x.iter_mut().for_each(|(_, _, pos)| *pos = new_pos),
|
||||
}
|
||||
|
||||
self
|
||||
|
@ -977,23 +977,25 @@ impl Engine {
|
||||
|
||||
// Share statement
|
||||
#[cfg(not(feature = "no_closure"))]
|
||||
Stmt::Share(x, pos) => {
|
||||
let (name, index) = &**x;
|
||||
Stmt::Share(x) => {
|
||||
x.iter()
|
||||
.try_for_each(|(name, index, pos)| {
|
||||
if let Some(index) = index
|
||||
.map(|n| scope.len() - n.get())
|
||||
.or_else(|| scope.search(name))
|
||||
{
|
||||
let val = scope.get_mut_by_index(index);
|
||||
|
||||
if let Some(index) = index
|
||||
.map(|n| scope.len() - n.get())
|
||||
.or_else(|| scope.search(name))
|
||||
{
|
||||
let val = scope.get_mut_by_index(index);
|
||||
|
||||
if !val.is_shared() {
|
||||
// Replace the variable with a shared value.
|
||||
*val = std::mem::take(val).into_shared();
|
||||
}
|
||||
Ok(Dynamic::UNIT)
|
||||
} else {
|
||||
Err(ERR::ErrorVariableNotFound(name.to_string(), *pos).into())
|
||||
}
|
||||
if !val.is_shared() {
|
||||
// Replace the variable with a shared value.
|
||||
*val = std::mem::take(val).into_shared();
|
||||
}
|
||||
Ok(())
|
||||
} else {
|
||||
Err(ERR::ErrorVariableNotFound(name.to_string(), *pos).into())
|
||||
}
|
||||
})
|
||||
.map(|_| Dynamic::UNIT)
|
||||
}
|
||||
|
||||
_ => unreachable!("statement cannot be evaluated: {:?}", stmt),
|
||||
|
@ -3739,15 +3739,17 @@ impl Engine {
|
||||
|
||||
// Convert the entire expression into a statement block, then insert the relevant
|
||||
// [`Share`][Stmt::Share] statements.
|
||||
let mut statements = StaticVec::with_capacity(externals.len() + 1);
|
||||
statements.extend(
|
||||
let mut statements = StaticVec::with_capacity(2);
|
||||
statements.push(Stmt::Share(
|
||||
externals
|
||||
.into_iter()
|
||||
.map(|crate::ast::Ident { name, pos }| {
|
||||
let (index, _) = parent.access_var(&name, lib, pos);
|
||||
Stmt::Share((name, index).into(), pos)
|
||||
}),
|
||||
);
|
||||
(name, index, pos)
|
||||
})
|
||||
.collect::<crate::FnArgsVec<_>>()
|
||||
.into(),
|
||||
));
|
||||
statements.push(Stmt::Expr(expr.into()));
|
||||
Expr::Stmt(crate::ast::StmtBlock::new(statements, pos, Position::NONE).into())
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user