diff --git a/src/errors.rs b/src/errors.rs index ccf1fee..f40c8be 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -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:"), } } diff --git a/src/virtualmachine.rs b/src/virtualmachine.rs index a1f0bc5..0647b02 100644 --- a/src/virtualmachine.rs +++ b/src/virtualmachine.rs @@ -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, memory: &mut Vec, 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, memory: &mut Vec { - 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); } } },