prepare the error system for try/catch

This commit is contained in:
afonya 2025-06-18 13:14:58 +02:00
parent 1a98959be0
commit 3dd28cedd3
Signed by: afonya
GPG key ID: EBB9C4CAFAAFB2DC
7 changed files with 146 additions and 118 deletions

View file

@ -1,5 +1,5 @@
use std::{any::Any, collections::HashMap, process, vec};
use crate::{decompiler::{operation_to_name, process, DecompiledFunction, DecompiledOperation}, enviroment, errors::{create_error, print_error, ErrorSubType, ErrorType}, Context};
use crate::{decompiler::{operation_to_name, process, DecompiledFunction, DecompiledOperation}, enviroment, errors::{create_error, print_error, ASLError, ErrorSubType, ErrorType}, Context};
#[derive(Debug, Clone)]
pub enum VMMemory {
@ -64,6 +64,14 @@ pub struct CallStack {
pub pc: usize,
}
#[derive(Debug, Clone)]
enum VMState {
Running,
Paused,
Finished,
Error(ASLError),
}
pub struct Machine {
pub memory: Vec<VMMemory>,
functions: Vec<DecompiledFunction>,
@ -73,6 +81,7 @@ pub struct Machine {
pub env: HashMap<String, VMMemory>,
pub ctx: Vec<Context>,
pub storage: Vec<Box<dyn Any>>,
pub state: VMState,
}
fn get_register_by_id(registers: &Vec<Register>, id: u8) -> Option<&Register> {
@ -181,14 +190,14 @@ fn do_operation_operation(registers: &mut Vec<Register>, memory: &mut Vec<VMMemo
let reg2 = get_register_by_id(&reg_clone, operation.arg2 as u8);
let reg3 = get_register_by_id(&reg_clone, operation.arg3);
if reg1.is_none() || reg2.is_none() || reg3.is_none() {
let err = create_error(&format!("One or more registers not found for operation"), operation.pos, ErrorType::MachineError, ErrorSubType::RegisterNotFound);
let err = create_error(&format!("One or more registers not found for operation"), operation.pos, ErrorType::MachineError, ErrorSubType::RegisterNotFound, ctx);
print_error(&err, &ctx);
process::exit(1);
}
let mem1 = reg1.unwrap().pointer;
let mem2 = reg2.unwrap().pointer;
if mem1 >= memory.len() || mem2 >= memory.len() || mem1 < 1 || mem2 < 1 {
let err = create_error(&format!("Memory location out of bounds `{}` or `{}`", mem1, mem2), operation.pos, ErrorType::MachineError, ErrorSubType::MemoryOutOfBounds);
let err = create_error(&format!("Memory location out of bounds `{}` or `{}`", mem1, mem2), operation.pos, ErrorType::MachineError, ErrorSubType::MemoryOutOfBounds, ctx);
print_error(&err, &ctx);
process::exit(1);
}
@ -207,7 +216,7 @@ fn do_operation_operation(registers: &mut Vec<Register>, memory: &mut Vec<VMMemo
},
13 => {
if num2.value == 0.0 {
let err = create_error(&format!("Division by zero"), operation.pos, ErrorType::MathError, ErrorSubType::DivisionByZero);
let err = create_error(&format!("Division by zero"), operation.pos, ErrorType::MathError, ErrorSubType::DivisionByZero, ctx);
print_error(&err, &ctx);
process::exit(1);
}
@ -238,7 +247,7 @@ fn do_operation_operation(registers: &mut Vec<Register>, memory: &mut Vec<VMMemo
result = VMMemory::Boolean(VMMemoryBoolean { value: num1.value <= num2.value, variable_id: 0 });
},
_ => {
let err = create_error(&format!("Unknown operation code for number operation: `{}`", operation.opcode), operation.pos, ErrorType::MachineError, ErrorSubType::UnknownOPCode);
let err = create_error(&format!("Unknown operation code for number operation: `{}`", operation.opcode), operation.pos, ErrorType::MachineError, ErrorSubType::UnknownOPCode, ctx);
print_error(&err, &ctx);
process::exit(1);
}
@ -256,7 +265,7 @@ fn do_operation_operation(registers: &mut Vec<Register>, memory: &mut Vec<VMMemo
result = VMMemory::Boolean(VMMemoryBoolean { value: str1.value != str2.value, variable_id: 0 });
},
_ => {
let err = create_error(&format!("Unknown operation code for string operation: `{}`", operation.opcode), operation.pos, ErrorType::MachineError, ErrorSubType::UnknownOPCode);
let err = create_error(&format!("Unknown operation code for string operation: `{}`", operation.opcode), operation.pos, ErrorType::MachineError, ErrorSubType::UnknownOPCode, ctx);
print_error(&err, &ctx);
process::exit(1);
}
@ -277,7 +286,7 @@ fn do_operation_operation(registers: &mut Vec<Register>, memory: &mut Vec<VMMemo
result = VMMemory::Boolean(VMMemoryBoolean { value: bool1.value != bool2.value, variable_id: 0 });
},
_ => {
let err = create_error(&format!("Unknown operation code for boolean operation: `{}`", operation.opcode), operation.pos, ErrorType::MachineError, ErrorSubType::UnknownOPCode);
let err = create_error(&format!("Unknown operation code for boolean operation: `{}`", operation.opcode), operation.pos, ErrorType::MachineError, ErrorSubType::UnknownOPCode, ctx);
print_error(&err, &ctx);
process::exit(1);
}
@ -292,14 +301,14 @@ fn do_operation_operation(registers: &mut Vec<Register>, memory: &mut Vec<VMMemo
result = VMMemory::Boolean(VMMemoryBoolean { value: false, variable_id: 0 });
},
_ => {
let err = create_error(&format!("Unknown operation code for null operation: `{}`", operation.opcode), operation.pos, ErrorType::MachineError, ErrorSubType::UnknownOPCode);
let err = create_error(&format!("Unknown operation code for null operation: `{}`", operation.opcode), operation.pos, ErrorType::MachineError, ErrorSubType::UnknownOPCode, ctx);
print_error(&err, &ctx);
process::exit(1);
}
};
},
_ => {
let err = create_error(&format!("Wrong memory types for operation: `{}`, position: `{}` and `{}`", operation_to_name(operation.opcode), mem1, mem2), operation.pos, ErrorType::TypeError, ErrorSubType::WrongType);
let err = create_error(&format!("Wrong memory types for operation: `{}`, position: `{}` and `{}`", operation_to_name(operation.opcode), mem1, mem2), operation.pos, ErrorType::TypeError, ErrorSubType::WrongType, ctx);
print_error(&err, &ctx);
process::exit(1);
}
@ -339,15 +348,23 @@ impl Machine {
env: enviroment::generate(),
ctx: ctx,
storage: Vec::new(),
state: VMState::Finished
};
}
pub fn load(&mut self, data: &Vec<u8>) {
let dec = process(data);
self.functions = dec.functions;
self.state = VMState::Paused
}
pub fn run(&mut self) {
pub fn resume(&mut self) {
match self.state {
VMState::Paused => {},
_ => {
panic!("Unable to resume VM, current state is not paused");
}
};
if self.call_stack.len() == 0 {
return;
}
@ -355,12 +372,19 @@ impl Machine {
let executed_func = func_clone.get(self.call_stack[self.call_stack.len()-1].func);
let mut executed_stack = self.call_stack.len()-1;
if executed_func.is_none() {
let err = create_error(&format!("Current function not found"), 1, ErrorType::MachineError, ErrorSubType::UnknownFunction);
let err = create_error(&format!("Current function not found"), 1, ErrorType::MachineError, ErrorSubType::UnknownFunction, &self.ctx[self.call_stack[executed_stack].func].clone());
print_error(&err, &self.ctx[self.call_stack[executed_stack].func].clone());
process::exit(1);
}
let mut executed_func = executed_func.unwrap();
self.state = VMState::Running;
while self.call_stack[executed_stack].pc < executed_func.body.len() {
match self.state {
VMState::Running => {},
_ => {
return;
}
};
let operation = &executed_func.body[self.call_stack[executed_stack].pc];
self.call_stack[executed_stack].pc += 1;
match operation.opcode {
@ -372,7 +396,7 @@ impl Machine {
//LDS
let str = executed_func.strings.get(&(operation.arg2 as u32));
if str.is_none() {
let err = create_error(&format!("String with ID `{}` not found", operation.arg2), operation.pos, ErrorType::MachineError, ErrorSubType::UnknownString);
let err = create_error(&format!("String with ID `{}` not found", operation.arg2), operation.pos, ErrorType::MachineError, ErrorSubType::UnknownString, &self.ctx[self.call_stack[executed_stack].func].clone());
print_error(&err, &self.ctx[self.call_stack[executed_stack].func].clone());
process::exit(1);
}
@ -384,13 +408,13 @@ impl Machine {
//LDM
let mem = get_mem_pos_by_var_id(&self.memory, operation.arg2 as u32);
if mem.is_none() {
let err = create_error(&format!("Memory with variable ID `{}` not found", operation.arg2), operation.pos, ErrorType::MachineError, ErrorSubType::UnknownMemoryLocation);
let err = create_error(&format!("Memory with variable ID `{}` not found", operation.arg2), operation.pos, ErrorType::MachineError, ErrorSubType::UnknownMemoryLocation, &self.ctx[self.call_stack[executed_stack].func].clone());
print_error(&err, &self.ctx[self.call_stack[executed_stack].func].clone());
process::exit(1);
}
let mem = mem.unwrap();
if mem >= self.memory.len() || mem < 1 {
let err = create_error(&format!("Memory location out of bounds for variable ID `{}`", operation.arg2), operation.pos, ErrorType::MachineError, ErrorSubType::MemoryOutOfBounds);
let err = create_error(&format!("Memory location out of bounds for variable ID `{}`", operation.arg2), operation.pos, ErrorType::MachineError, ErrorSubType::MemoryOutOfBounds, &self.ctx[self.call_stack[executed_stack].func].clone());
print_error(&err, &self.ctx[self.call_stack[executed_stack].func].clone());
process::exit(1);
}
@ -435,14 +459,14 @@ impl Machine {
//LDF
let func_pos = executed_func.functions.get(&(operation.arg2 as u32));
if func_pos.is_none() {
let err = create_error(&format!("Function with ID `{}` not found", operation.arg2), operation.pos, ErrorType::MachineError, ErrorSubType::UnknownFunction);
let err = create_error(&format!("Function with ID `{}` not found", operation.arg2), operation.pos, ErrorType::MachineError, ErrorSubType::UnknownFunction, &self.ctx[self.call_stack[executed_stack].func].clone());
print_error(&err, &self.ctx[self.call_stack[executed_stack].func].clone());
process::exit(1);
}
let func_pos = func_pos.unwrap();
let func = self.functions.get(*func_pos as usize);
if func.is_none() {
let err = create_error(&format!("Function with position `{}` not found", func_pos), operation.pos, ErrorType::MachineError, ErrorSubType::UnknownFunction);
let err = create_error(&format!("Function with position `{}` not found", func_pos), operation.pos, ErrorType::MachineError, ErrorSubType::UnknownFunction, &self.ctx[self.call_stack[executed_stack].func].clone());
print_error(&err, &self.ctx[self.call_stack[executed_stack].func].clone());
process::exit(1);
}
@ -466,13 +490,13 @@ impl Machine {
//ASS
let reg = get_register_by_id(&self.registers, operation.arg1);
if reg.is_none() {
let err = create_error(&format!("Register `{}` not found", operation.arg1), operation.pos, ErrorType::MachineError, ErrorSubType::RegisterNotFound);
let err = create_error(&format!("Register `{}` not found", operation.arg1), operation.pos, ErrorType::MachineError, ErrorSubType::RegisterNotFound, &self.ctx[self.call_stack[executed_stack].func].clone());
print_error(&err, &self.ctx[self.call_stack[executed_stack].func].clone());
process::exit(1);
}
let reg = reg.unwrap();
if reg.pointer >= self.memory.len() || reg.pointer < 1 {
let err = create_error(&format!("Register `{}` points to an invalid memory location", operation.arg1), operation.pos, ErrorType::MachineError, ErrorSubType::MemoryOutOfBounds);
let err = create_error(&format!("Register `{}` points to an invalid memory location", operation.arg1), operation.pos, ErrorType::MachineError, ErrorSubType::MemoryOutOfBounds, &self.ctx[self.call_stack[executed_stack].func].clone());
print_error(&err, &self.ctx[self.call_stack[executed_stack].func].clone());
process::exit(1);
}
@ -491,7 +515,7 @@ impl Machine {
let temp_regs = self.registers.clone();
let reg1 = get_register_by_id(&temp_regs, operation.arg1);
if reg1.is_none() {
let err = create_error(&format!("Register `{}` not found", operation.arg1), operation.pos, ErrorType::MachineError, ErrorSubType::RegisterNotFound);
let err = create_error(&format!("Register `{}` not found", operation.arg1), operation.pos, ErrorType::MachineError, ErrorSubType::RegisterNotFound, &self.ctx[self.call_stack[executed_stack].func].clone());
print_error(&err, &self.ctx[self.call_stack[executed_stack].func].clone());
process::exit(1);
}
@ -507,13 +531,13 @@ impl Machine {
let reg1 = get_register_by_id(&reg_clone, operation.arg1);
let reg2 = get_register_by_id(&reg_clone, operation.arg2 as u8);
if reg1.is_none() || reg2.is_none() {
let err = create_error(&format!("Register `{}` or `{}` not found", operation.arg1, operation.arg2), operation.pos, ErrorType::MachineError, ErrorSubType::RegisterNotFound);
let err = create_error(&format!("Register `{}` or `{}` not found", operation.arg1, operation.arg2), operation.pos, ErrorType::MachineError, ErrorSubType::RegisterNotFound, &self.ctx[self.call_stack[executed_stack].func].clone());
print_error(&err, &self.ctx[self.call_stack[executed_stack].func].clone());
process::exit(1);
}
let mem1 = reg1.unwrap().pointer;
if mem1 >= self.memory.len() || mem1 < 1 {
let err = create_error(&format!("Memory location out of bounds for register `{}`", operation.arg1), operation.pos, ErrorType::MachineError, ErrorSubType::MemoryOutOfBounds);
let err = create_error(&format!("Memory location out of bounds for register `{}`", operation.arg1), operation.pos, ErrorType::MachineError, ErrorSubType::MemoryOutOfBounds, &self.ctx[self.call_stack[executed_stack].func].clone());
print_error(&err, &self.ctx[self.call_stack[executed_stack].func].clone());
process::exit(1);
}
@ -523,7 +547,7 @@ impl Machine {
result = VMMemory::Boolean(VMMemoryBoolean { value: !bool.value, variable_id: 0 });
},
_ => {
let err = create_error(&format!("Wrong memory type for NOT operation, position: `{}`", mem1), operation.pos, ErrorType::TypeError, ErrorSubType::WrongType);
let err = create_error(&format!("Wrong memory type for NOT operation, position: `{}`", mem1), operation.pos, ErrorType::TypeError, ErrorSubType::WrongType, &self.ctx[self.call_stack[executed_stack].func].clone());
print_error(&err, &self.ctx[self.call_stack[executed_stack].func].clone());
process::exit(1);
}
@ -546,14 +570,14 @@ impl Machine {
//CJP
let reg = get_register_by_id(&self.registers, operation.arg1);
if reg.is_none() {
let err = create_error(&format!("Register `{}` not found", operation.arg1), operation.pos, ErrorType::MachineError, ErrorSubType::RegisterNotFound);
let err = create_error(&format!("Register `{}` not found", operation.arg1), operation.pos, ErrorType::MachineError, ErrorSubType::RegisterNotFound, &self.ctx[self.call_stack[executed_stack].func].clone());
print_error(&err, &self.ctx[self.call_stack[executed_stack].func].clone());
process::exit(1);
}
let reg = reg.unwrap();
let mem = self.memory.get(reg.pointer);
if mem.is_none() {
let err = create_error(&format!("Memory location not found for register `{}`", operation.arg1), operation.pos, ErrorType::MachineError, ErrorSubType::UnknownMemoryLocation);
let err = create_error(&format!("Memory location not found for register `{}`", operation.arg1), operation.pos, ErrorType::MachineError, ErrorSubType::UnknownMemoryLocation, &self.ctx[self.call_stack[executed_stack].func].clone());
print_error(&err, &self.ctx[self.call_stack[executed_stack].func].clone());
process::exit(1);
}
@ -565,7 +589,7 @@ impl Machine {
}
}
_ => {
let err = create_error(&format!("Wrong memory type for CJP operation, position: `{}`", reg.pointer), operation.pos, ErrorType::TypeError, ErrorSubType::WrongType);
let err = create_error(&format!("Wrong memory type for CJP operation, position: `{}`", reg.pointer), operation.pos, ErrorType::TypeError, ErrorSubType::WrongType, &self.ctx[self.call_stack[executed_stack].func].clone());
print_error(&err, &self.ctx[self.call_stack[executed_stack].func].clone());
process::exit(1);
},
@ -575,14 +599,14 @@ impl Machine {
//CAL
let reg = get_register_by_id(&self.registers, operation.arg1);
if reg.is_none() {
let err = create_error(&format!("Register `{}` not found", operation.arg1), operation.pos, ErrorType::MachineError, ErrorSubType::RegisterNotFound);
let err = create_error(&format!("Register `{}` not found", operation.arg1), operation.pos, ErrorType::MachineError, ErrorSubType::RegisterNotFound, &self.ctx[self.call_stack[executed_stack].func].clone());
print_error(&err, &self.ctx[self.call_stack[executed_stack].func].clone());
process::exit(1);
}
let reg = reg.unwrap();
let mem = self.memory.get(reg.pointer);
if mem.is_none() {
let err = create_error(&format!("Memory location not found for register `{}`", operation.arg1), operation.pos, ErrorType::MachineError, ErrorSubType::UnknownMemoryLocation);
let err = create_error(&format!("Memory location not found for register `{}`", operation.arg1), operation.pos, ErrorType::MachineError, ErrorSubType::UnknownMemoryLocation, &self.ctx[self.call_stack[executed_stack].func].clone());
print_error(&err, &self.ctx[self.call_stack[executed_stack].func].clone());
process::exit(1);
}
@ -593,7 +617,7 @@ impl Machine {
for i in &self.stack {
let mut new_mem = i.clone();
if self.functions[func.id].variables.len() <= arg || self.functions[func.id].variables[arg].start != 0 {
let err = create_error(&format!("Too many arguments supplied for function: `{}`", func.id), operation.pos, ErrorType::SemanticError, ErrorSubType::TooManyArguments);
let err = create_error(&format!("Too many arguments supplied for function: `{}`", func.id), operation.pos, ErrorType::SemanticError, ErrorSubType::TooManyArguments, &self.ctx[self.call_stack[executed_stack].func].clone());
print_error(&err, &self.ctx[self.call_stack[executed_stack].func].clone());
process::exit(1);
}
@ -610,7 +634,7 @@ impl Machine {
let mut result = (nfunc.func)(self, &operation, self.stack.clone());
let ret_reg = get_register_by_id(&self.registers, operation.arg2 as u8);
if ret_reg.is_none() {
let err = create_error(&format!("Register `{}` not found", operation.arg2), operation.pos, ErrorType::MachineError, ErrorSubType::RegisterNotFound);
let err = create_error(&format!("Register `{}` not found", operation.arg2), operation.pos, ErrorType::MachineError, ErrorSubType::RegisterNotFound, &self.ctx[self.call_stack[executed_stack].func].clone());
print_error(&err, &self.ctx[self.call_stack[executed_stack].func].clone());
process::exit(1);
}
@ -627,7 +651,7 @@ impl Machine {
self.stack.clear();
},
_ => {
let err = create_error(&format!("Unable to call non-function type"), operation.pos, ErrorType::MachineError, ErrorSubType::NonFunctionCall);
let err = create_error(&format!("Unable to call non-function type"), operation.pos, ErrorType::MachineError, ErrorSubType::NonFunctionCall, &self.ctx[self.call_stack[executed_stack].func].clone());
print_error(&err, &self.ctx[self.call_stack[executed_stack].func].clone());
process::exit(1);
}
@ -637,14 +661,14 @@ impl Machine {
//PSH
let reg = get_register_by_id(&self.registers, operation.arg1);
if reg.is_none() {
let err = create_error(&format!("Register `{}` not found", operation.arg1), operation.pos, ErrorType::MachineError, ErrorSubType::RegisterNotFound);
let err = create_error(&format!("Register `{}` not found", operation.arg1), operation.pos, ErrorType::MachineError, ErrorSubType::RegisterNotFound, &self.ctx[self.call_stack[executed_stack].func].clone());
print_error(&err, &self.ctx[self.call_stack[executed_stack].func].clone());
process::exit(1);
}
let reg = reg.unwrap();
let mem = self.memory.get(reg.pointer);
if mem.is_none() {
let err = create_error(&format!("Memory location not found for register `{}`", operation.arg1), operation.pos, ErrorType::MachineError, ErrorSubType::MemoryOutOfBounds);
let err = create_error(&format!("Memory location not found for register `{}`", operation.arg1), operation.pos, ErrorType::MachineError, ErrorSubType::MemoryOutOfBounds, &self.ctx[self.call_stack[executed_stack].func].clone());
print_error(&err, &self.ctx[self.call_stack[executed_stack].func].clone());
process::exit(1);
}
@ -656,13 +680,13 @@ impl Machine {
let target_reg = get_register_by_id(&self.registers, self.call_stack[executed_stack].return_reg as u8);
let ret_reg = get_register_by_id(&self.registers, operation.arg1);
if target_reg.is_none() || ret_reg.is_none() {
let err = create_error(&format!("Register `{}` or `{}` not found", self.call_stack[executed_stack].return_reg, operation.arg1), operation.pos, ErrorType::MachineError, ErrorSubType::RegisterNotFound);
let err = create_error(&format!("Register `{}` or `{}` not found", self.call_stack[executed_stack].return_reg, operation.arg1), operation.pos, ErrorType::MachineError, ErrorSubType::RegisterNotFound, &self.ctx[self.call_stack[executed_stack].func].clone());
print_error(&err, &self.ctx[self.call_stack[executed_stack].func].clone());
process::exit(1);
}
let ret_mem = self.memory.get(ret_reg.unwrap().pointer);
if ret_mem.is_none() {
let err = create_error(&format!("Memory location not found for register `{}`", operation.arg1), operation.pos, ErrorType::MachineError, ErrorSubType::MemoryOutOfBounds);
let err = create_error(&format!("Memory location not found for register `{}`", operation.arg1), operation.pos, ErrorType::MachineError, ErrorSubType::MemoryOutOfBounds, &self.ctx[self.call_stack[executed_stack].func].clone());
print_error(&err, &self.ctx[self.call_stack[executed_stack].func].clone());
process::exit(1);
}
@ -686,13 +710,13 @@ impl Machine {
let reg2 = get_register_by_id(&reg_clone, operation.arg2 as u8);
let reg3 = get_register_by_id(&reg_clone, operation.arg3);
if reg2.is_none() || reg3.is_none() {
let err = create_error(&format!("Register `{}` or `{}` not found", operation.arg2, operation.arg3), operation.pos, ErrorType::MachineError, ErrorSubType::RegisterNotFound);
let err = create_error(&format!("Register `{}` or `{}` not found", operation.arg2, operation.arg3), operation.pos, ErrorType::MachineError, ErrorSubType::RegisterNotFound, &self.ctx[self.call_stack[executed_stack].func].clone());
print_error(&err, &self.ctx[self.call_stack[executed_stack].func].clone());
process::exit(1);
}
let mem2 = self.memory.get(reg2.unwrap().pointer);
if mem2.is_none() {
let err = create_error(&format!("Memory location out of bounds for register `{}`", operation.arg2), operation.pos, ErrorType::MachineError, ErrorSubType::MemoryOutOfBounds);
let err = create_error(&format!("Memory location out of bounds for register `{}`", operation.arg2), operation.pos, ErrorType::MachineError, ErrorSubType::MemoryOutOfBounds, &self.ctx[self.call_stack[executed_stack].func].clone());
print_error(&err, &self.ctx[self.call_stack[executed_stack].func].clone());
process::exit(1);
}
@ -708,7 +732,7 @@ impl Machine {
}
},
_ => {
let err = create_error(&format!("Only string keys are allowed for GET enviroment"), operation.pos, ErrorType::TypeError, ErrorSubType::WrongType);
let err = create_error(&format!("Only string keys are allowed for GET enviroment"), operation.pos, ErrorType::TypeError, ErrorSubType::WrongType, &self.ctx[self.call_stack[executed_stack].func].clone());
print_error(&err, &self.ctx[self.call_stack[executed_stack].func].clone());
process::exit(1);
}
@ -728,14 +752,14 @@ impl Machine {
let reg2 = get_register_by_id(&reg_clone, operation.arg2 as u8);
let reg3 = get_register_by_id(&reg_clone, operation.arg3);
if reg.is_none() || reg2.is_none() || reg3.is_none() {
let err = create_error(&format!("Register `{}` or `{}` or `{}` not found", operation.arg1, operation.arg2, operation.arg3), operation.pos, ErrorType::MachineError, ErrorSubType::RegisterNotFound);
let err = create_error(&format!("Register `{}` or `{}` or `{}` not found", operation.arg1, operation.arg2, operation.arg3), operation.pos, ErrorType::MachineError, ErrorSubType::RegisterNotFound, &self.ctx[self.call_stack[executed_stack].func].clone());
print_error(&err, &self.ctx[self.call_stack[executed_stack].func].clone());
process::exit(1);
}
let mem1 = self.memory.get(reg.unwrap().pointer);
let mem2 = self.memory.get(reg2.unwrap().pointer);
if mem1.is_none() || mem2.is_none() {
let err = create_error(&format!("Memory location not found for register `{}` or `{}`", operation.arg1, operation.arg2), operation.pos, ErrorType::MachineError, ErrorSubType::MemoryOutOfBounds);
let err = create_error(&format!("Memory location not found for register `{}` or `{}`", operation.arg1, operation.arg2), operation.pos, ErrorType::MachineError, ErrorSubType::MemoryOutOfBounds, &self.ctx[self.call_stack[executed_stack].func].clone());
print_error(&err, &self.ctx[self.call_stack[executed_stack].func].clone());
process::exit(1);
}
@ -752,7 +776,7 @@ impl Machine {
}
},
_ => {
let err = create_error(&format!("Wrong memory type for GET operation, position: `{}`", reg.unwrap().pointer), operation.pos, ErrorType::TypeError, ErrorSubType::WrongType);
let err = create_error(&format!("Wrong memory type for GET operation, position: `{}`", reg.unwrap().pointer), operation.pos, ErrorType::TypeError, ErrorSubType::WrongType, &self.ctx[self.call_stack[executed_stack].func].clone());
print_error(&err, &self.ctx[self.call_stack[executed_stack].func].clone());
process::exit(1);
}
@ -773,7 +797,7 @@ impl Machine {
let reg2 = get_register_by_id(&self.registers, operation.arg2 as u8);
let reg3 = get_register_by_id(&self.registers, operation.arg3);
if reg.is_none() || reg2.is_none() || reg3.is_none() {
let err = create_error(&format!("Register `{}` or `{}` or `{}` not found", operation.arg1, operation.arg2, operation.arg3), operation.pos, ErrorType::MachineError, ErrorSubType::RegisterNotFound);
let err = create_error(&format!("Register `{}` or `{}` or `{}` not found", operation.arg1, operation.arg2, operation.arg3), operation.pos, ErrorType::MachineError, ErrorSubType::RegisterNotFound, &self.ctx[self.call_stack[executed_stack].func].clone());
print_error(&err, &self.ctx[self.call_stack[executed_stack].func].clone());
process::exit(1);
}
@ -781,7 +805,7 @@ impl Machine {
let mem2 = self.memory.get(reg2.unwrap().pointer);
let mem3 = self.memory.get(reg3.unwrap().pointer);
if mem1.is_none() || mem2.is_none() || mem3.is_none() {
let err = create_error(&format!("Memory location not found for register `{}` or `{}` or `{}`", operation.arg1, operation.arg2, operation.arg3), operation.pos, ErrorType::MachineError, ErrorSubType::MemoryOutOfBounds);
let err = create_error(&format!("Memory location not found for register `{}` or `{}` or `{}`", operation.arg1, operation.arg2, operation.arg3), operation.pos, ErrorType::MachineError, ErrorSubType::MemoryOutOfBounds, &self.ctx[self.call_stack[executed_stack].func].clone());
print_error(&err, &self.ctx[self.call_stack[executed_stack].func].clone());
process::exit(1);
}
@ -793,18 +817,19 @@ impl Machine {
set_mem_tbl_val(tbl, mem2, mem3);
},
_ => {
let err = create_error(&format!("Wrong memory type for SET operation, position: `{}`", reg.unwrap().pointer), operation.pos, ErrorType::TypeError, ErrorSubType::WrongType);
let err = create_error(&format!("Wrong memory type for SET operation, position: `{}`", reg.unwrap().pointer), operation.pos, ErrorType::TypeError, ErrorSubType::WrongType, &self.ctx[self.call_stack[executed_stack].func].clone());
print_error(&err, &self.ctx[self.call_stack[executed_stack].func].clone());
process::exit(1);
}
}
},
_ => {
let err = create_error(&format!("Unknown operation code: `{}`", operation.opcode), operation.pos, ErrorType::MachineError, ErrorSubType::UnknownOPCode);
let err = create_error(&format!("Unknown operation code: `{}`", operation.opcode), operation.pos, ErrorType::MachineError, ErrorSubType::UnknownOPCode, &self.ctx[self.call_stack[executed_stack].func].clone());
print_error(&err, &self.ctx[self.call_stack[executed_stack].func].clone());
process::exit(1);
}
}
}
self.state = VMState::Finished;
}
}