Introduce JumpLabels instead of manually correct jump positions
Signed-off-by: Marcel Müller <neikos@neikos.email>
This commit is contained in:
parent
e64256b65f
commit
7182024342
12 changed files with 485 additions and 381 deletions
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue