Add index to Share statement.

This commit is contained in:
Stephen Chung 2022-10-25 10:05:31 +08:00
parent 6880d44900
commit 6702fe349c
5 changed files with 25 additions and 14 deletions

View File

@ -614,7 +614,10 @@ pub enum Stmt {
/// 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 a normal variable into a shared variable when the variable is _captured_ by a closure.
#[cfg(not(feature = "no_closure"))] #[cfg(not(feature = "no_closure"))]
Share(crate::ImmutableString, Position), Share(
Box<(crate::ImmutableString, Option<NonZeroUsize>)>,
Position,
),
} }
impl Default for Stmt { impl Default for Stmt {

View File

@ -188,7 +188,7 @@ impl Engine {
// Find the variable in the scope // Find the variable in the scope
let var_name = expr.get_variable_name(true).expect("`Expr::Variable`"); let var_name = expr.get_variable_name(true).expect("`Expr::Variable`");
match scope.get_index(var_name) { match scope.search(var_name) {
Some(index) => index, Some(index) => index,
None => { None => {
return match self.global_modules.iter().find_map(|m| m.get_var(var_name)) { return match self.global_modules.iter().find_map(|m| m.get_var(var_name)) {

View File

@ -959,7 +959,7 @@ impl Engine {
Stmt::Export(x, ..) => { Stmt::Export(x, ..) => {
let (Ident { name, pos, .. }, Ident { name: alias, .. }) = &**x; let (Ident { name, pos, .. }, Ident { name: alias, .. }) = &**x;
// Mark scope variables as public // Mark scope variables as public
if let Some(index) = scope.get_index(name) { if let Some(index) = scope.search(name) {
let alias = if alias.is_empty() { name } else { alias }.clone(); let alias = if alias.is_empty() { name } else { alias }.clone();
scope.add_alias_by_index(index, alias.into()); scope.add_alias_by_index(index, alias.into());
Ok(Dynamic::UNIT) Ok(Dynamic::UNIT)
@ -970,8 +970,13 @@ impl Engine {
// Share statement // Share statement
#[cfg(not(feature = "no_closure"))] #[cfg(not(feature = "no_closure"))]
Stmt::Share(name, pos) => { Stmt::Share(x, pos) => {
if let Some(index) = scope.get_index(name) { let (name, index) = &**x;
if let Some(index) = index
.map(|n| scope.len() - n.get())
.or_else(|| scope.search(name))
{
let val = scope.get_mut_by_index(index); let val = scope.get_mut_by_index(index);
if !val.is_shared() { if !val.is_shared() {

View File

@ -3711,7 +3711,10 @@ impl Engine {
statements.extend( statements.extend(
externals externals
.into_iter() .into_iter()
.map(|crate::ast::Ident { name, pos }| Stmt::Share(name, pos)), .map(|crate::ast::Ident { name, pos }| {
let (index, _) = parent.access_var(&name, lib, pos);
Stmt::Share((name, index).into(), pos)
}),
); );
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())

View File

@ -407,7 +407,7 @@ impl Scope<'_> {
/// Find an entry in the [`Scope`], starting from the last. /// Find an entry in the [`Scope`], starting from the last.
#[inline] #[inline]
#[must_use] #[must_use]
pub(crate) fn get_index(&self, name: &str) -> Option<usize> { pub(crate) fn search(&self, name: &str) -> Option<usize> {
let len = self.len(); let len = self.len();
self.names self.names
@ -467,7 +467,7 @@ impl Scope<'_> {
#[inline] #[inline]
#[must_use] #[must_use]
pub fn is_constant(&self, name: &str) -> Option<bool> { pub fn is_constant(&self, name: &str) -> Option<bool> {
self.get_index(name) self.search(name)
.map(|n| match self.values[n].access_mode() { .map(|n| match self.values[n].access_mode() {
AccessMode::ReadWrite => false, AccessMode::ReadWrite => false,
AccessMode::ReadOnly => true, AccessMode::ReadOnly => true,
@ -505,7 +505,7 @@ impl Scope<'_> {
value: impl Variant + Clone, value: impl Variant + Clone,
) -> &mut Self { ) -> &mut Self {
match self match self
.get_index(name.as_ref()) .search(name.as_ref())
.map(|n| (n, self.values[n].access_mode())) .map(|n| (n, self.values[n].access_mode()))
{ {
None | Some((.., AccessMode::ReadOnly)) => { None | Some((.., AccessMode::ReadOnly)) => {
@ -547,7 +547,7 @@ impl Scope<'_> {
value: impl Variant + Clone, value: impl Variant + Clone,
) -> &mut Self { ) -> &mut Self {
match self match self
.get_index(name.as_ref()) .search(name.as_ref())
.map(|n| (n, self.values[n].access_mode())) .map(|n| (n, self.values[n].access_mode()))
{ {
None => { None => {
@ -583,7 +583,7 @@ impl Scope<'_> {
#[inline(always)] #[inline(always)]
#[must_use] #[must_use]
pub fn get(&self, name: &str) -> Option<&Dynamic> { pub fn get(&self, name: &str) -> Option<&Dynamic> {
self.get_index(name).map(|index| &self.values[index]) self.search(name).map(|index| &self.values[index])
} }
/// Remove the last entry in the [`Scope`] by the specified name and return its value. /// Remove the last entry in the [`Scope`] by the specified name and return its value.
/// ///
@ -614,7 +614,7 @@ impl Scope<'_> {
#[inline(always)] #[inline(always)]
#[must_use] #[must_use]
pub fn remove<T: Variant + Clone>(&mut self, name: &str) -> Option<T> { pub fn remove<T: Variant + Clone>(&mut self, name: &str) -> Option<T> {
self.get_index(name).and_then(|index| { self.search(name).and_then(|index| {
self.names.remove(index); self.names.remove(index);
self.aliases.remove(index); self.aliases.remove(index);
self.values.remove(index).try_cast() self.values.remove(index).try_cast()
@ -646,7 +646,7 @@ impl Scope<'_> {
#[inline] #[inline]
#[must_use] #[must_use]
pub fn get_mut(&mut self, name: &str) -> Option<&mut Dynamic> { pub fn get_mut(&mut self, name: &str) -> Option<&mut Dynamic> {
self.get_index(name) self.search(name)
.and_then(move |n| match self.values[n].access_mode() { .and_then(move |n| match self.values[n].access_mode() {
AccessMode::ReadWrite => Some(self.get_mut_by_index(n)), AccessMode::ReadWrite => Some(self.get_mut_by_index(n)),
AccessMode::ReadOnly => None, AccessMode::ReadOnly => None,
@ -692,7 +692,7 @@ impl Scope<'_> {
name: impl AsRef<str> + Into<Identifier>, name: impl AsRef<str> + Into<Identifier>,
alias: impl Into<Identifier>, alias: impl Into<Identifier>,
) { ) {
if let Some(index) = self.get_index(name.as_ref()) { if let Some(index) = self.search(name.as_ref()) {
let alias = match alias.into() { let alias = match alias.into() {
x if x.is_empty() => name.into(), x if x.is_empty() => name.into(),
x => x, x => x,