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