implement the new error system for the VM too

This commit is contained in:
afonya2 2025-06-08 21:50:17 +02:00
parent 532fffe725
commit 3e94e4a1dd
Signed by: afonya
GPG key ID: EBB9C4CAFAAFB2DC
2 changed files with 90 additions and 22 deletions

View file

@ -1,5 +1,3 @@
use std::f32::consts::E;
use crate::Context;
pub enum ErrorType {
@ -25,6 +23,7 @@ pub enum ErrorSubType {
VariableNotFound,
VariableAlreadyExists,
ArgumentDuplication,
TooManyArguments,
//Machine errors
RegisterNotFound,
MemoryOutOfBounds,
@ -38,7 +37,6 @@ pub enum ErrorSubType {
//Type errors
InvalidType,
WrongType,
NonStringKey,
}
pub struct ASLError {
@ -91,7 +89,7 @@ fn convert_subtypes_to_string(stype: &ErrorSubType) -> String {
ErrorSubType::DivisionByZero => String::from("Division by zero"),
ErrorSubType::InvalidType => String::from("Invalid type"),
ErrorSubType::WrongType => String::from("Wrong type"),
ErrorSubType::NonStringKey => String::from("Non-string key"),
ErrorSubType::TooManyArguments => String::from("Too many arguments"),
}
}
fn convert_subtypes_to_short(stype: &ErrorSubType) -> String {
@ -118,7 +116,7 @@ fn convert_subtypes_to_short(stype: &ErrorSubType) -> String {
ErrorSubType::DivisionByZero => String::from("DZ:"),
ErrorSubType::InvalidType => String::from("IT:"),
ErrorSubType::WrongType => String::from("WT:"),
ErrorSubType::NonStringKey => String::from("NS:"),
ErrorSubType::TooManyArguments => String::from("TA:"),
}
}

View file

@ -229,6 +229,44 @@ fn get_mem_tbl_val(tbl: &VMMemoryTable, key: VMMemory) -> Option<&VMMemory> {
None
}
fn operation_to_name(opcode: u8) -> String {
match opcode {
0 => "HLT".to_string(),
1 => "LDS".to_string(),
2 => "LDM".to_string(),
3 => "LDI".to_string(),
4 => "LDB".to_string(),
5 => "LDF".to_string(),
6 => "LDN".to_string(),
7 => "ASS".to_string(),
8 => "UNB".to_string(),
9 => "MOV".to_string(),
10 => "ADD".to_string(),
11 => "SUB".to_string(),
12 => "MUL".to_string(),
13 => "DIV".to_string(),
14 => "POW".to_string(),
15 => "MOD".to_string(),
16 => "AND".to_string(),
17 => "OR".to_string(),
18 => "EQ".to_string(),
19 => "NEQ".to_string(),
20 => "GRE".to_string(),
21 => "GRQ".to_string(),
22 => "LES".to_string(),
23 => "LEQ".to_string(),
24 => "NOT".to_string(),
25 => "JMP".to_string(),
26 => "CJP".to_string(),
27 => "CAL".to_string(),
28 => "PSH".to_string(),
29 => "RET".to_string(),
30 => "GET".to_string(),
31 => "SET".to_string(),
_ => panic!("Unknown operation code: {}", opcode),
}
}
fn do_operation_operation(registers: &mut Vec<Register>, memory: &mut Vec<VMMemory>, operation: &DecompiledOperation, ctx: &Context) {
let reg_clone = registers.clone();
let reg1 = get_register_by_id(&reg_clone, operation.arg1);
@ -353,7 +391,7 @@ fn do_operation_operation(registers: &mut Vec<Register>, memory: &mut Vec<VMMemo
};
},
_ => {
let err = create_error(&format!("Invalid memory types for operation: `{}` and `{}`", mem1, mem2), operation.pos, ErrorType::TypeError, ErrorSubType::InvalidType);
let err = create_error(&format!("Wrong memory types for operation: `{}`, position: `{}` and `{}`", operation_to_name(operation.opcode), mem1, mem2), operation.pos, ErrorType::TypeError, ErrorSubType::InvalidType);
print_error(&err, &ctx);
process::exit(1);
}
@ -503,7 +541,7 @@ impl Machine {
panic!("Unsupported ASX version");
}
let _func_count = read_be_num(&data[6..10]);
let mut offset = 6;
let mut offset = 10;
while offset < data.len() {
let func = load_func(data.clone(), &mut offset);
self.functions.push(func);
@ -720,7 +758,9 @@ impl Machine {
}
let mem1 = reg1.unwrap().pointer;
if mem1 >= self.memory.len() || mem1 < 1 {
panic!("Memory location out of bounds for register {}", operation.arg1);
let err = create_error(&format!("Memory location out of bounds for register `{}`", operation.arg1), 0, ErrorType::MachineError, ErrorSubType::MemoryOutOfBounds);
print_error(&err, &self.ctx[self.call_stack[executed_stack].func].clone());
process::exit(1);
}
let mut result: VMMemory;
match &self.memory[mem1] {
@ -728,7 +768,9 @@ impl Machine {
result = VMMemory::Boolean(VMMemoryBoolean { value: !bool.value, variable_id: 0 });
},
_ => {
panic!("Invalid memory types for operation: {}", mem1);
let err = create_error(&format!("Wrong memory type for NOT operation, position: `{}`", mem1), 0, ErrorType::TypeError, ErrorSubType::WrongType);
print_error(&err, &self.ctx[self.call_stack[executed_stack].func].clone());
process::exit(1);
}
}
let mut reg2_pointer = reg2.unwrap().pointer;
@ -786,7 +828,9 @@ impl Machine {
let reg = reg.unwrap();
let mem = self.memory.get(reg.pointer);
if mem.is_none() {
panic!("Memory location not found for register");
let err = create_error(&format!("Memory location not found for register `{}`", operation.arg1), 0, ErrorType::MachineError, ErrorSubType::UnknownMemoryLocation);
print_error(&err, &self.ctx[self.call_stack[executed_stack].func].clone());
process::exit(1);
}
let mem = mem.unwrap();
match &mem {
@ -795,7 +839,11 @@ impl Machine {
self.call_stack[executed_stack].pc = operation.arg2 as usize;
}
}
_ => panic!("Invalid memory type for CJP operation"),
_ => {
let err = create_error(&format!("Wrong memory type for CJP operation, position: `{}`", reg.pointer), 0, ErrorType::TypeError, ErrorSubType::WrongType);
print_error(&err, &self.ctx[self.call_stack[executed_stack].func].clone());
process::exit(1);
},
}
},
27 => {
@ -809,7 +857,9 @@ impl Machine {
let reg = reg.unwrap();
let mem = self.memory.get(reg.pointer);
if mem.is_none() {
panic!("Memory location not found for register");
let err = create_error(&format!("Memory location not found for register `{}`", operation.arg1), 0, ErrorType::MachineError, ErrorSubType::UnknownMemoryLocation);
print_error(&err, &self.ctx[self.call_stack[executed_stack].func].clone());
process::exit(1);
}
let mem = mem.unwrap().clone();
match mem {
@ -818,7 +868,9 @@ 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 {
panic!("Function {} does not have enough arguments", func.id);
let err = create_error(&format!("Too many arguments supplied for function: `{}`", func.id), 0, ErrorType::SemanticError, ErrorSubType::TooManyArguments);
print_error(&err, &self.ctx[self.call_stack[executed_stack].func].clone());
process::exit(1);
}
match &mut new_mem {
VMMemory::String(str) => {
@ -856,7 +908,9 @@ impl Machine {
self.stack.clear();
},
_ => {
panic!("Unable to call non-function memory type");
let err = create_error(&format!("Unable to call non-function type"), 0, ErrorType::MachineError, ErrorSubType::NonFunctionCall);
print_error(&err, &self.ctx[self.call_stack[executed_stack].func].clone());
process::exit(1);
}
}
},
@ -871,7 +925,9 @@ impl Machine {
let reg = reg.unwrap();
let mem = self.memory.get(reg.pointer);
if mem.is_none() {
panic!("Memory location not found for register");
let err = create_error(&format!("Memory location not found for register `{}`", operation.arg1), 0, ErrorType::MachineError, ErrorSubType::MemoryOutOfBounds);
print_error(&err, &self.ctx[self.call_stack[executed_stack].func].clone());
process::exit(1);
}
let mem = mem.unwrap();
self.stack.push(mem.clone());
@ -887,7 +943,9 @@ impl Machine {
}
let ret_mem = self.memory.get(ret_reg.unwrap().pointer);
if ret_mem.is_none() {
panic!("Memory location not found for return register");
let err = create_error(&format!("Memory location not found for register `{}`", operation.arg1), 0, ErrorType::MachineError, ErrorSubType::MemoryOutOfBounds);
print_error(&err, &self.ctx[self.call_stack[executed_stack].func].clone());
process::exit(1);
}
let return_value = ret_mem.unwrap().clone();
let target_reg_pointer = self.memory.len();
@ -915,7 +973,9 @@ impl Machine {
}
let mem2 = self.memory.get(reg2.unwrap().pointer);
if mem2.is_none() {
panic!("Memory location not found for register {}", operation.arg2);
let err = create_error(&format!("Memory location out of bounds for register `{}`", operation.arg2), 0, ErrorType::MachineError, ErrorSubType::MemoryOutOfBounds);
print_error(&err, &self.ctx[self.call_stack[executed_stack].func].clone());
process::exit(1);
}
let mem2 = mem2.unwrap().clone();
let mut result: VMMemory;
@ -929,7 +989,9 @@ impl Machine {
}
},
_ => {
panic!("Unable to get non-string key from enviroment");
let err = create_error(&format!("Only string keys are allowed for GET enviroment"), 0, ErrorType::TypeError, ErrorSubType::WrongType);
print_error(&err, &self.ctx[self.call_stack[executed_stack].func].clone());
process::exit(1);
}
}
let mut reg3_pointer = reg3.unwrap().pointer;
@ -984,7 +1046,9 @@ impl Machine {
let mem1 = self.memory.get(reg.unwrap().pointer);
let mem2 = self.memory.get(reg2.unwrap().pointer);
if mem1.is_none() || mem2.is_none() {
panic!("Memory location not found for one or more registers");
let err = create_error(&format!("Memory location not found for register `{}` or `{}`", operation.arg1, operation.arg2), 0, ErrorType::MachineError, ErrorSubType::MemoryOutOfBounds);
print_error(&err, &self.ctx[self.call_stack[executed_stack].func].clone());
process::exit(1);
}
let mem1 = mem1.unwrap().clone();
let mem2 = mem2.unwrap().clone();
@ -999,7 +1063,9 @@ impl Machine {
}
},
_ => {
panic!("Invalid memory type for GET operation");
let err = create_error(&format!("Wrong memory type for GET operation, position: `{}`", reg.unwrap().pointer), 0, ErrorType::TypeError, ErrorSubType::WrongType);
print_error(&err, &self.ctx[self.call_stack[executed_stack].func].clone());
process::exit(1);
}
}
let mut reg3_pointer = reg3.unwrap().pointer;
@ -1056,7 +1122,9 @@ 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() {
panic!("Memory location not found for one or more registers");
let err = create_error(&format!("Memory location not found for register `{}` or `{}` or `{}`", operation.arg1, operation.arg2, operation.arg3), 0, ErrorType::MachineError, ErrorSubType::MemoryOutOfBounds);
print_error(&err, &self.ctx[self.call_stack[executed_stack].func].clone());
process::exit(1);
}
let mem2 = mem2.unwrap().clone();
let mem3 = mem3.unwrap().clone();
@ -1066,7 +1134,9 @@ impl Machine {
set_mem_tbl_val(tbl, mem2, mem3);
},
_ => {
panic!("Invalid memory type for SET operation");
let err = create_error(&format!("Wrong memory type for SET operation, position: `{}`", reg.unwrap().pointer), 0, ErrorType::TypeError, ErrorSubType::WrongType);
print_error(&err, &self.ctx[self.call_stack[executed_stack].func].clone());
process::exit(1);
}
}
},