Use variable dereferencing to improve language

This commit is contained in:
Jeff 2024-08-28 12:15:14 -04:00
parent 0c3e8d5edf
commit 8043e24637

View File

@ -242,12 +242,16 @@ impl Vm {
let position = value.position(); let position = value.position();
let value = self let value = self
.run_expression(value, collect_garbage)? .run_expression(value, collect_garbage)?
.expect_value(position)? .expect_value(position)?;
.into_raw() let new_value = match value {
.into_reference(); Value::Mutable(_) => {
return Err(RuntimeError::CannotAssignToMutable { position })
}
_ => value,
};
self.context self.context
.set_variable_value(identifier.inner, value) .set_variable_value(identifier.inner, new_value)
.map_err(|error| RuntimeError::ContextError { error, position })?; .map_err(|error| RuntimeError::ContextError { error, position })?;
Ok(()) Ok(())
@ -257,7 +261,6 @@ impl Vm {
let mutable_value = self let mutable_value = self
.run_expression(value, collect_garbage)? .run_expression(value, collect_garbage)?
.expect_value(position)? .expect_value(position)?
.into_raw()
.into_mutable(); .into_mutable();
self.context self.context
@ -988,8 +991,7 @@ impl Vm {
let position = repeat_operand.position(); let position = repeat_operand.position();
let value = self let value = self
.run_expression(repeat_operand, collect_garbage)? .run_expression(repeat_operand, collect_garbage)?
.expect_value(position)? .expect_value(position)?;
.into_raw();
Ok(Evaluation::Return(Some(Value::list(vec![ Ok(Evaluation::Return(Some(Value::list(vec![
value; value;
@ -1436,8 +1438,8 @@ mod tests {
} }
#[test] #[test]
fn mutate_copied_variable() { fn dereference_copied_variable() {
let source = "let mut x = 42; let y = [x; 3]; x += 1; y"; let source = "let mut x = 42; let y = [*x; 3]; x += 1; y";
assert_eq!( assert_eq!(
run(source), run(source),
@ -1460,8 +1462,8 @@ mod tests {
} }
#[test] #[test]
fn mutate_assigned_variable() { fn dereference_mutable_variable() {
let source = "let mut x = 42; let y = x; x += 1; y"; let source = "let mut x = 42; let y = *x; x += 1; y";
assert_eq!(run(source), Ok(Some(Value::integer(42)))); assert_eq!(run(source), Ok(Some(Value::integer(42))));
} }