Clean up context garbage collection
This commit is contained in:
parent
14aa7c242a
commit
2a0e4c9b78
@ -135,7 +135,6 @@ impl<'a> Analyzer<'a> {
|
|||||||
StructType::Unit {
|
StructType::Unit {
|
||||||
name: name.inner.clone(),
|
name: name.inner.clone(),
|
||||||
},
|
},
|
||||||
statement.position(),
|
|
||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
StructDefinition::Tuple { name, items } => {
|
StructDefinition::Tuple { name, items } => {
|
||||||
@ -147,7 +146,6 @@ impl<'a> Analyzer<'a> {
|
|||||||
name: name.inner.clone(),
|
name: name.inner.clone(),
|
||||||
fields,
|
fields,
|
||||||
},
|
},
|
||||||
statement.position(),
|
|
||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
StructDefinition::Fields { name, fields } => {
|
StructDefinition::Fields { name, fields } => {
|
||||||
@ -164,7 +162,6 @@ impl<'a> Analyzer<'a> {
|
|||||||
name: name.inner.clone(),
|
name: name.inner.clone(),
|
||||||
fields,
|
fields,
|
||||||
},
|
},
|
||||||
statement.position(),
|
|
||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -5,9 +5,9 @@ use std::{
|
|||||||
sync::{Arc, PoisonError, RwLock, RwLockReadGuard, RwLockWriteGuard},
|
sync::{Arc, PoisonError, RwLock, RwLockReadGuard, RwLockWriteGuard},
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{ast::Span, Constructor, Identifier, StructType, Type, Value};
|
use crate::{Constructor, Identifier, StructType, Type, Value};
|
||||||
|
|
||||||
pub type Associations = HashMap<Identifier, (ContextData, Span)>;
|
pub type Associations = HashMap<Identifier, (ContextData, usize)>;
|
||||||
|
|
||||||
/// Garbage-collecting context for variables.
|
/// Garbage-collecting context for variables.
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
@ -64,7 +64,7 @@ impl Context {
|
|||||||
pub fn get(
|
pub fn get(
|
||||||
&self,
|
&self,
|
||||||
identifier: &Identifier,
|
identifier: &Identifier,
|
||||||
) -> Result<Option<(ContextData, Span)>, ContextError> {
|
) -> Result<Option<(ContextData, usize)>, ContextError> {
|
||||||
let associations = self.associations.read()?;
|
let associations = self.associations.read()?;
|
||||||
|
|
||||||
Ok(associations.get(identifier).cloned())
|
Ok(associations.get(identifier).cloned())
|
||||||
@ -223,20 +223,13 @@ impl Context {
|
|||||||
&self,
|
&self,
|
||||||
identifier: Identifier,
|
identifier: Identifier,
|
||||||
struct_type: StructType,
|
struct_type: StructType,
|
||||||
position: Span,
|
|
||||||
) -> Result<(), ContextError> {
|
) -> Result<(), ContextError> {
|
||||||
log::trace!("Setting {identifier} to constructor of type {struct_type}");
|
log::trace!("Setting {identifier} to constructor of type {struct_type}");
|
||||||
|
|
||||||
let mut variables = self.associations.write()?;
|
let mut variables = self.associations.write()?;
|
||||||
let last_position = variables
|
let last_position = variables
|
||||||
.get(&identifier)
|
.get(&identifier)
|
||||||
.map(|(_, last_position)| {
|
.map(|(_, last_position)| *last_position)
|
||||||
if last_position.1 > position.1 {
|
|
||||||
*last_position
|
|
||||||
} else {
|
|
||||||
position
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
|
|
||||||
variables.insert(
|
variables.insert(
|
||||||
@ -248,13 +241,13 @@ impl Context {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Collects garbage up to the given position, removing all variables with lesser positions.
|
/// Collects garbage up to the given position, removing all variables with lesser positions.
|
||||||
pub fn collect_garbage(&self, position_end: usize) -> Result<(), ContextError> {
|
pub fn collect_garbage(&self, position: usize) -> Result<(), ContextError> {
|
||||||
log::trace!("Collecting garbage up to {position_end}");
|
log::trace!("Collecting garbage up to {position}");
|
||||||
|
|
||||||
let mut variables = self.associations.write()?;
|
let mut variables = self.associations.write()?;
|
||||||
|
|
||||||
variables.retain(|identifier, (_, last_used)| {
|
variables.retain(|identifier, (_, last_used)| {
|
||||||
let should_drop = position_end >= last_used.1;
|
let should_drop = position >= *last_used;
|
||||||
|
|
||||||
if should_drop {
|
if should_drop {
|
||||||
log::trace!("Removing {identifier}");
|
log::trace!("Removing {identifier}");
|
||||||
@ -274,12 +267,12 @@ impl Context {
|
|||||||
pub fn update_last_position(
|
pub fn update_last_position(
|
||||||
&self,
|
&self,
|
||||||
identifier: &Identifier,
|
identifier: &Identifier,
|
||||||
position: Span,
|
position: usize,
|
||||||
) -> Result<bool, ContextError> {
|
) -> Result<bool, ContextError> {
|
||||||
let mut associations = self.associations.write()?;
|
let mut associations = self.associations.write()?;
|
||||||
|
|
||||||
if let Some((_, last_position)) = associations.get_mut(identifier) {
|
if let Some((_, last_position)) = associations.get_mut(identifier) {
|
||||||
if position.1 > last_position.1 {
|
if position > *last_position {
|
||||||
log::trace!("Updating {identifier}'s last position to {position:?}");
|
log::trace!("Updating {identifier}'s last position to {position:?}");
|
||||||
|
|
||||||
*last_position = position;
|
*last_position = position;
|
||||||
|
@ -13,7 +13,7 @@ pub fn core_library<'a>() -> &'a Context {
|
|||||||
ContextData::VariableValue(Value::function(Function::BuiltIn(
|
ContextData::VariableValue(Value::function(Function::BuiltIn(
|
||||||
BuiltInFunction::ToString,
|
BuiltInFunction::ToString,
|
||||||
))),
|
))),
|
||||||
(0, 0),
|
0,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
@ -22,7 +22,7 @@ pub fn core_library<'a>() -> &'a Context {
|
|||||||
ContextData::VariableValue(Value::function(Function::BuiltIn(
|
ContextData::VariableValue(Value::function(Function::BuiltIn(
|
||||||
BuiltInFunction::ReadLine,
|
BuiltInFunction::ReadLine,
|
||||||
))),
|
))),
|
||||||
(0, 0),
|
0,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
@ -31,7 +31,7 @@ pub fn core_library<'a>() -> &'a Context {
|
|||||||
ContextData::VariableValue(Value::function(Function::BuiltIn(
|
ContextData::VariableValue(Value::function(Function::BuiltIn(
|
||||||
BuiltInFunction::WriteLine,
|
BuiltInFunction::WriteLine,
|
||||||
))),
|
))),
|
||||||
(0, 0),
|
0,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
]))
|
]))
|
||||||
|
@ -455,7 +455,7 @@ impl<'src> Parser<'src> {
|
|||||||
let identifier = Identifier::new(text);
|
let identifier = Identifier::new(text);
|
||||||
|
|
||||||
if let ParserMode::Condition = self.mode {
|
if let ParserMode::Condition = self.mode {
|
||||||
context.update_last_position(&identifier, start_position)?;
|
context.update_last_position(&identifier, start_position.1)?;
|
||||||
|
|
||||||
return Ok(Expression::identifier(identifier, start_position));
|
return Ok(Expression::identifier(identifier, start_position));
|
||||||
}
|
}
|
||||||
@ -496,7 +496,7 @@ impl<'src> Parser<'src> {
|
|||||||
|
|
||||||
let position = (start_position.0, self.current_position.1);
|
let position = (start_position.0, self.current_position.1);
|
||||||
|
|
||||||
context.update_last_position(&identifier, position)?;
|
context.update_last_position(&identifier, position.1)?;
|
||||||
|
|
||||||
return Ok(Expression::r#struct(
|
return Ok(Expression::r#struct(
|
||||||
StructExpression::Fields { name, fields },
|
StructExpression::Fields { name, fields },
|
||||||
@ -504,7 +504,7 @@ impl<'src> Parser<'src> {
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
context.update_last_position(&identifier, start_position)?;
|
context.update_last_position(&identifier, start_position.1)?;
|
||||||
|
|
||||||
Ok(Expression::identifier(identifier, start_position))
|
Ok(Expression::identifier(identifier, start_position))
|
||||||
}
|
}
|
||||||
@ -988,7 +988,7 @@ impl<'src> Parser<'src> {
|
|||||||
|
|
||||||
self.next_token()?;
|
self.next_token()?;
|
||||||
|
|
||||||
context.update_last_position(&identifier, position)?;
|
context.update_last_position(&identifier, position.1)?;
|
||||||
|
|
||||||
Ok(Node::new(identifier, position))
|
Ok(Node::new(identifier, position))
|
||||||
} else {
|
} else {
|
||||||
|
Loading…
Reference in New Issue
Block a user