1
0

Simplify and clean up

This commit is contained in:
Jeff 2024-10-19 03:06:14 -04:00
parent 6bcc5b1555
commit 8c79157fa7
3 changed files with 28 additions and 100 deletions

View File

@ -11,7 +11,7 @@ use crate::{AnnotatedError, Identifier, Instruction, Operation, Span, Type, Valu
#[derive(Clone, PartialOrd, Ord, Serialize, Deserialize)]
pub struct Chunk {
instructions: Vec<(Instruction, Span)>,
constants: Vec<Option<Value>>,
constants: Vec<Value>,
locals: Vec<Local>,
scope_depth: usize,
}
@ -33,7 +33,7 @@ impl Chunk {
) -> Self {
Self {
instructions,
constants: constants.into_iter().map(Some).collect(),
constants,
locals,
scope_depth: 0,
}
@ -126,8 +126,8 @@ impl Chunk {
operations
}
pub fn constants(&self) -> &[Option<Value>] {
&self.constants
pub fn take_constants(self) -> Vec<Value> {
self.constants
}
pub fn get_constant(&self, index: u8, position: Span) -> Result<&Value, ChunkError> {
@ -136,21 +136,6 @@ impl Chunk {
self.constants
.get(index)
.ok_or(ChunkError::ConstantIndexOutOfBounds { index, position })
.and_then(|value| {
value
.as_ref()
.ok_or(ChunkError::ConstantAlreadyUsed { index, position })
})
}
pub fn take_constant(&mut self, index: u8, position: Span) -> Result<Value, ChunkError> {
let index = index as usize;
self.constants
.get_mut(index)
.ok_or_else(|| ChunkError::ConstantIndexOutOfBounds { index, position })?
.take()
.ok_or(ChunkError::ConstantAlreadyUsed { index, position })
}
pub fn push_constant(&mut self, value: Value, position: Span) -> Result<u8, ChunkError> {
@ -159,7 +144,7 @@ impl Chunk {
if starting_length + 1 > (u8::MAX as usize) {
Err(ChunkError::ConstantOverflow { position })
} else {
self.constants.push(Some(value));
self.constants.push(value);
Ok(starting_length as u8)
}
@ -518,7 +503,6 @@ impl<'a> ChunkDisassembler<'a> {
};
let push_function_disassembly = |function_disassembly: &str, disassembly: &mut String| {
disassembly.push_str(function_disassembly);
disassembly.push('\n');
};
let mut disassembly = String::new();
let top_border = "".to_string() + &"".repeat(self.width - 2) + "";
@ -616,17 +600,12 @@ impl<'a> ChunkDisassembler<'a> {
push_header(line, &mut disassembly);
}
for (index, value_option) in self.chunk.constants.iter().enumerate() {
let value_display = value_option
.as_ref()
.map(|value| value.to_string())
.unwrap_or("empty".to_string());
let constant_display = format!("{index:<5} {value_display:<5}");
for (index, value) in self.chunk.constants.iter().enumerate() {
let constant_display = format!("{index:<5} {value:<5}");
push_details(&constant_display, &mut disassembly);
if let Some(function_disassembly) =
value_option.as_ref().and_then(|value| match value {
if let Some(function_disassembly) = match value {
Value::Function(function) => Some({
let mut disassembler = function.chunk().disassembler("function");
disassembler.indent = self.indent + 1;
@ -636,8 +615,7 @@ impl<'a> ChunkDisassembler<'a> {
}),
Value::Primitive(_) => None,
Value::Object(_) => None,
})
{
} {
push_function_disassembly(&function_disassembly, &mut disassembly);
}
}

View File

@ -1,6 +1,6 @@
use std::{
fmt::{self, Display, Formatter},
mem::{replace, take},
mem::replace,
num::{ParseFloatError, ParseIntError},
};

View File

@ -65,13 +65,7 @@ impl Vm {
);
match instruction.operation() {
Operation::Move => {
let to_register = instruction.a();
let from_register = instruction.b();
let value = self.take(from_register, to_register, position)?;
self.set(to_register, value, position)?;
}
Operation::Move => todo!(),
Operation::Close => {
let from_register = instruction.b();
let to_register = instruction.c();
@ -206,29 +200,7 @@ impl Vm {
self.ip += 1;
}
}
Operation::TestSet => {
let to_register = instruction.a();
let argument = instruction.b();
let test_value = instruction.c_as_boolean();
let borrowed_value = self.get(argument, position)?;
let boolean =
if let Value::Primitive(Primitive::Boolean(boolean)) = borrowed_value {
*boolean
} else {
return Err(VmError::ExpectedBoolean {
found: borrowed_value.clone(),
position,
});
};
if boolean == test_value {
let value = self.take(argument, to_register, position)?;
self.set(to_register, value, position)?;
} else {
self.ip += 1;
}
}
Operation::TestSet => todo!(),
Operation::Equal => {
debug_assert_eq!(
self.chunk.get_instruction(self.ip, position)?.0.operation(),
@ -398,8 +370,6 @@ impl Vm {
if let Some(value) = return_value {
self.set(function_index, value, position)?;
} else {
self.empty(function_index, position)?;
}
}
Operation::Return => {
@ -430,14 +400,14 @@ impl Vm {
match to_register.cmp(&length) {
Ordering::Less => {
log::trace!("Replace R{to_register} with {value}");
log::trace!("Change R{to_register} to {value}");
self.stack[to_register] = Register::Value(value);
Ok(())
}
Ordering::Equal => {
log::trace!("Push R{to_register} with {value}");
log::trace!("Set R{to_register} to {value}");
self.stack.push(Register::Value(value));
@ -466,14 +436,14 @@ impl Vm {
match to_register.cmp(&length) {
Ordering::Less => {
log::trace!("Replace R{to_register} with R{from_register}");
log::trace!("Change R{to_register} to R{from_register}");
self.stack[to_register] = Register::Pointer(from_register);
Ok(())
}
Ordering::Equal => {
log::trace!("Push R{to_register} with R{from_register}");
log::trace!("Set R{to_register} to R{from_register}");
self.stack.push(Register::Pointer(from_register));
@ -501,7 +471,7 @@ impl Vm {
}
if index == length {
log::trace!("Push register {index} with constant {constant_index}");
log::trace!("Change register {index} to C{constant_index}");
self.stack.push(Register::Constant(constant_index));
@ -509,7 +479,7 @@ impl Vm {
}
if index < length {
log::trace!("Replace register {index} with constant {constant_index}");
log::trace!("Set register {index} to C{constant_index}");
self.stack[index] = Register::Constant(constant_index);
@ -546,27 +516,7 @@ impl Vm {
}
}
fn take(&mut self, index: u8, point_to: u8, position: Span) -> Result<Value, VmError> {
let index = index as usize;
let register = replace(&mut self.stack[index], Register::Pointer(point_to));
match register {
Register::Value(value) => Ok(value),
Register::Pointer(register_index) => {
let value = self.take(register_index, point_to, position)?;
Ok(value)
}
Register::Constant(constant_index) => {
let value = self.chunk.take_constant(constant_index, position)?;
Ok(value)
}
Register::Empty => Err(VmError::EmptyRegister { index, position }),
}
}
fn empty(&mut self, index: u8, position: Span) -> Result<Value, VmError> {
fn empty(mut self, index: u8, position: Span) -> Result<Value, VmError> {
let index = index as usize;
if index >= self.stack.len() {
@ -583,7 +533,7 @@ impl Vm {
Ok(value)
}
Register::Constant(constant_index) => {
let value = self.chunk.take_constant(constant_index, position)?;
let value = self.chunk.take_constants().remove(constant_index as usize);
Ok(value)
}