1
0

Fix parsing bug that fixes garbage collection bug

This commit is contained in:
Jeff 2024-08-20 12:09:17 -04:00
parent 2e7acbeb64
commit 4846b3f74d
4 changed files with 22 additions and 25 deletions

View File

@ -93,7 +93,7 @@ impl<'recovered, 'a: 'recovered> Analyzer<'a> {
identifier.inner.clone(),
r#type,
identifier.position,
);
)?;
} else {
return Err(AnalysisError::ExpectedValueFromExpression {
expression: value.clone(),
@ -166,7 +166,7 @@ impl<'recovered, 'a: 'recovered> Analyzer<'a> {
field_access_expression.inner.as_ref();
self.context
.update_last_position(&field.inner, field.position);
.update_last_position(&field.inner, field.position)?;
self.analyze_expression(container)?;
}
Expression::Grouped(expression) => {
@ -174,7 +174,7 @@ impl<'recovered, 'a: 'recovered> Analyzer<'a> {
}
Expression::Identifier(identifier) => {
self.context
.update_last_position(&identifier.inner, identifier.position);
.update_last_position(&identifier.inner, identifier.position)?;
}
Expression::If(if_expression) => self.analyze_if(&if_expression.inner)?,
Expression::List(list_expression) => match list_expression.inner.as_ref() {
@ -291,7 +291,7 @@ impl<'recovered, 'a: 'recovered> Analyzer<'a> {
Expression::Struct(struct_expression) => match struct_expression.inner.as_ref() {
StructExpression::Fields { name, fields } => {
self.context
.update_last_position(&name.inner, name.position);
.update_last_position(&name.inner, name.position)?;
for (_, expression) in fields {
self.analyze_expression(expression)?;
@ -438,8 +438,8 @@ impl From<ContextError> for AnalysisError {
impl AnalysisError {
pub fn position(&self) -> Option<Span> {
let position = match self {
AnalysisError::AstError(ast_error) => return None,
AnalysisError::ContextError(context_error) => return None,
AnalysisError::AstError(ast_error) => return ast_error.position(),
AnalysisError::ContextError(_) => return None,
AnalysisError::ExpectedBoolean { actual } => actual.position(),
AnalysisError::ExpectedIdentifier { actual } => actual.position(),

View File

@ -204,13 +204,13 @@ impl Context {
}
/// Collects garbage up to the given position, removing all variables with lesser positions.
pub fn collect_garbage(&self, position: Span) -> Result<(), ContextError> {
log::trace!("Collecting garbage up to {position:?}");
pub fn collect_garbage(&self, position_end: usize) -> Result<(), ContextError> {
log::trace!("Collecting garbage up to {position_end}");
let mut variables = self.associations.write()?;
variables.retain(|identifier, (_, last_used)| {
let should_drop = position.0 > last_used.0 && position.1 > last_used.1;
let should_drop = position_end >= last_used.1;
if should_drop {
log::trace!("Removing {identifier}");
@ -327,8 +327,6 @@ mod tests {
#[test]
fn context_removes_variables() {
env_logger::builder().is_test(true).try_init().unwrap();
let source = "
let x = 5;
let y = 10;
@ -337,7 +335,10 @@ mod tests {
";
let context = Context::new();
run_with_context(source, context.clone()).unwrap();
assert_eq!(
run_with_context(source, context.clone()),
Ok(Some(Value::Integer(15)))
);
assert_eq!(context.association_count().unwrap(), 0);
}

View File

@ -636,7 +636,7 @@ impl<'src> Parser<'src> {
let condition = self.parse_expression(0)?;
let block = self.parse_block()?;
let position = (start_position.0, self.current_position.1);
let position = (start_position.0, block.position.1);
Ok(Expression::while_loop(condition, block, position))
}
@ -1228,7 +1228,7 @@ mod tests {
)]),
(28, 38),
),
(15, 39),
(15, 38),
),
(15, 39)
)),

View File

@ -57,7 +57,7 @@ pub fn run(source: &str) -> Result<Option<Value>, DustError> {
/// ```
pub fn run_with_context(source: &str, context: Context) -> Result<Option<Value>, DustError> {
let abstract_syntax_tree = parse(source)?;
let mut analyzer = Analyzer::new(&abstract_syntax_tree, context.clone());
let analyzer = Analyzer::new(&abstract_syntax_tree, context.clone());
analyzer
.analyze()
@ -159,14 +159,14 @@ impl Vm {
};
let constructor = struct_type.constructor();
self.context.set_constructor(name, constructor);
self.context.set_constructor(name, constructor)?;
Ok(None)
}
};
if collect_garbage {
// self.context.collect_garbage(position);
self.context.collect_garbage(position.1)?;
}
result.map_err(|error| RuntimeError::Statement {
@ -187,7 +187,7 @@ impl Vm {
.run_expression(value, collect_garbage)?
.expect_value(value_position)?;
self.context.set_variable_value(identifier.inner, value);
self.context.set_variable_value(identifier.inner, value)?;
Ok(())
}
@ -199,7 +199,7 @@ impl Vm {
.into_mutable();
self.context
.set_variable_value(identifier.inner, mutable_value);
.set_variable_value(identifier.inner, mutable_value)?;
Ok(())
}
@ -872,13 +872,7 @@ impl Vm {
let mut previous_value = None;
for statement in statements {
let position = statement.position();
previous_value = self.run_statement(statement, collect_garbage)?;
if collect_garbage {
// self.context.collect_garbage(position);
}
}
Ok(Evaluation::Return(previous_value))
@ -1468,6 +1462,8 @@ mod tests {
#[test]
fn while_loop() {
env_logger::builder().is_test(true).try_init().ok();
let input = "let mut x = 0; while x < 5 { x += 1 } x";
assert_eq!(run(input), Ok(Some(Value::mutable_from(5))));