Introduce JumpLabels instead of manually correct jump positions

Signed-off-by: Marcel Müller <neikos@neikos.email>
This commit is contained in:
Marcel Müller 2026-03-11 15:50:05 +01:00
parent e64256b65f
commit 7182024342
12 changed files with 485 additions and 381 deletions

View file

@ -5,6 +5,7 @@ use thiserror::Error;
use crate::Context;
use crate::emit::Instruction;
use crate::emit::VMInstructions;
use crate::input::NomoInput;
#[derive(Debug, Error, Display)]
@ -17,24 +18,21 @@ pub enum EvaluationError {
**
** This is an internal error and is a bug that should be reported
*/
InstructionPointerOverflow,
LabelNotFound,
}
pub fn execute(
instructions: &[Instruction],
global_context: &Context,
) -> Result<String, EvaluationError> {
pub fn execute(vm: &VMInstructions, global_context: &Context) -> Result<String, EvaluationError> {
let mut output = String::new();
let mut scopes: HashMap<crate::emit::VariableSlot, serde_json::Value> = HashMap::new();
let mut ip = 0;
loop {
if ip >= instructions.len() {
if ip >= vm.instructions.len() {
break;
}
let instr = instructions.get(ip).unwrap();
let instr = vm.instructions.get(ip).unwrap();
match instr {
Instruction::NoOp => (),
@ -58,25 +56,21 @@ pub fn execute(
if dont_jump {
// We are done
} else {
let (new_ip, overflow) = ip.overflowing_add_signed(*jump);
let Some(new_ip) = vm.labels.get(jump) else {
return Err(EvaluationError::LabelNotFound);
};
if overflow {
return Err(EvaluationError::InstructionPointerOverflow);
} else {
ip = new_ip;
continue;
}
ip = *new_ip;
continue;
}
}
Instruction::Jump { jump } => {
let (new_ip, overflow) = ip.overflowing_add_signed(*jump);
let Some(new_ip) = vm.labels.get(jump) else {
return Err(EvaluationError::LabelNotFound);
};
if overflow {
return Err(EvaluationError::InstructionPointerOverflow);
} else {
ip = new_ip;
continue;
}
ip = *new_ip;
continue;
}
}