implement the new error system for the VM too
This commit is contained in:
parent
532fffe725
commit
3e94e4a1dd
2 changed files with 90 additions and 22 deletions
|
@ -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:"),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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(®_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);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue