1
0

Add a VM method; Refactor and clean up

This commit is contained in:
Jeff 2024-10-13 04:21:07 -04:00
parent 055f0a4100
commit 5eb901f468
3 changed files with 63 additions and 25 deletions

View File

@ -529,7 +529,7 @@ impl<'a> ChunkDisassembler<'a> {
if let Some(source) = self.source { if let Some(source) = self.source {
push( push(
&source.replace("\n", ""), &source.split_whitespace().collect::<Vec<&str>>().join(" "),
&mut disassembly, &mut disassembly,
self.width, self.width,
self.indent, self.indent,

View File

@ -1170,7 +1170,6 @@ impl<'src> Parser<'src> {
} }
self.parse_expression()?; self.parse_expression()?;
self.increment_register()?;
argument_count += 1; argument_count += 1;
} }

View File

@ -1,4 +1,4 @@
use std::mem::replace; use std::{cmp::Ordering, mem::replace};
use crate::{ use crate::{
parse, value::Primitive, AnnotatedError, Chunk, ChunkError, DustError, Identifier, Instruction, parse, value::Primitive, AnnotatedError, Chunk, ChunkError, DustError, Identifier, Instruction,
@ -126,9 +126,8 @@ impl Vm {
let to_register = instruction.a(); let to_register = instruction.a();
let local_index = instruction.b(); let local_index = instruction.b();
let local = self.chunk.get_local(local_index, position)?; let local = self.chunk.get_local(local_index, position)?;
let value = self.take(local.register_index, to_register, position)?;
self.set(to_register, value, position)?; self.set_pointer(to_register, local.register_index, position)?;
} }
Operation::SetLocal => { Operation::SetLocal => {
let register = instruction.a(); let register = instruction.a();
@ -385,7 +384,7 @@ impl Vm {
let last_argument_index = first_argument_index + argument_count - 1; let last_argument_index = first_argument_index + argument_count - 1;
for argument_index in first_argument_index..=last_argument_index { for argument_index in first_argument_index..=last_argument_index {
let argument = self.empty(argument_index, position)?; let argument = self.get(argument_index, position)?.clone();
function_vm.stack.push(Register::Value(argument)); function_vm.stack.push(Register::Value(argument));
} }
@ -416,35 +415,71 @@ impl Vm {
Ok(None) Ok(None)
} }
fn set(&mut self, index: u8, value: Value, position: Span) -> Result<(), VmError> { fn set(&mut self, to_register: u8, value: Value, position: Span) -> Result<(), VmError> {
let length = self.stack.len(); let length = self.stack.len();
let index = index as usize; let to_register = to_register as usize;
if length == Self::STACK_LIMIT { if length == Self::STACK_LIMIT {
return Err(VmError::StackOverflow { position }); return Err(VmError::StackOverflow { position });
} }
if index == length { match to_register.cmp(&length) {
log::trace!("Push register {index} with value {value}"); Ordering::Less => {
log::trace!("Replace R{to_register} with {value}");
self.stack[to_register] = Register::Value(value);
Ok(())
}
Ordering::Equal => {
log::trace!("Push R{to_register} with {value}");
self.stack.push(Register::Value(value)); self.stack.push(Register::Value(value));
return Ok(()); Ok(())
} }
Ordering::Greater => Err(VmError::SkippedRegister {
if index < length { index: to_register,
log::trace!("Replace register {index} with value {value}"); length,
self.stack[index] = Register::Value(value);
return Ok(());
}
Err(VmError::SkippedRegister {
index,
length: self.stack.len(),
position, position,
}) }),
}
}
fn set_pointer(
&mut self,
to_register: u8,
from_register: u8,
position: Span,
) -> Result<(), VmError> {
let length = self.stack.len();
let to_register = to_register as usize;
if length == Self::STACK_LIMIT {
return Err(VmError::StackOverflow { position });
}
match to_register.cmp(&length) {
Ordering::Less => {
log::trace!("Replace R{to_register} with R{from_register}");
self.stack[to_register] = Register::Pointer(from_register);
Ok(())
}
Ordering::Equal => {
log::trace!("Push R{to_register} with R{from_register}");
self.stack.push(Register::Pointer(from_register));
Ok(())
}
Ordering::Greater => Err(VmError::SkippedRegister {
index: to_register,
length,
position,
}),
}
} }
fn set_constant( fn set_constant(
@ -488,7 +523,7 @@ impl Vm {
let register = self let register = self
.stack .stack
.get(index) .get(index)
.ok_or_else(|| VmError::RegisterIndexOutOfBounds { position })?; .ok_or_else(|| VmError::RegisterIndexOutOfBounds { index, position })?;
match register { match register {
Register::Value(value) => Ok(value), Register::Value(value) => Ok(value),
@ -530,7 +565,7 @@ impl Vm {
let index = index as usize; let index = index as usize;
if index >= self.stack.len() { if index >= self.stack.len() {
return Err(VmError::RegisterIndexOutOfBounds { position }); return Err(VmError::RegisterIndexOutOfBounds { index, position });
} }
let register = replace(&mut self.stack[index], Register::Empty); let register = replace(&mut self.stack[index], Register::Empty);
@ -587,6 +622,7 @@ pub enum VmError {
position: Span, position: Span,
}, },
RegisterIndexOutOfBounds { RegisterIndexOutOfBounds {
index: usize,
position: Span, position: Span,
}, },
InvalidInstruction { InvalidInstruction {
@ -649,6 +685,9 @@ impl AnnotatedError for VmError {
match self { match self {
Self::EmptyRegister { index, .. } => Some(format!("Register {index} is empty")), Self::EmptyRegister { index, .. } => Some(format!("Register {index} is empty")),
Self::ExpectedFunction { found, .. } => Some(format!("{found} is not a function")), Self::ExpectedFunction { found, .. } => Some(format!("{found} is not a function")),
Self::RegisterIndexOutOfBounds { index, .. } => {
Some(format!("R{index} does not exist at this time"))
}
Self::UndefinedVariable { identifier, .. } => { Self::UndefinedVariable { identifier, .. } => {
Some(format!("{identifier} is not in scope")) Some(format!("{identifier} is not in scope"))
} }
@ -664,7 +703,7 @@ impl AnnotatedError for VmError {
Self::EmptyRegister { position, .. } => *position, Self::EmptyRegister { position, .. } => *position,
Self::ExpectedBoolean { position, .. } => *position, Self::ExpectedBoolean { position, .. } => *position,
Self::ExpectedFunction { position, .. } => *position, Self::ExpectedFunction { position, .. } => *position,
Self::RegisterIndexOutOfBounds { position } => *position, Self::RegisterIndexOutOfBounds { position, .. } => *position,
Self::InvalidInstruction { position, .. } => *position, Self::InvalidInstruction { position, .. } => *position,
Self::SkippedRegister { position, .. } => *position, Self::SkippedRegister { position, .. } => *position,
Self::StackUnderflow { position } => *position, Self::StackUnderflow { position } => *position,