Fix parsing bug that fixes garbage collection bug
This commit is contained in:
parent
2e7acbeb64
commit
4846b3f74d
@ -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(),
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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)
|
||||
)),
|
||||
|
@ -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))));
|
||||
|
Loading…
Reference in New Issue
Block a user