begin new error system, unfinished

This commit is contained in:
afonya2 2025-06-06 22:01:53 +02:00
parent 32c2a20697
commit 532fffe725
Signed by: afonya
GPG key ID: EBB9C4CAFAAFB2DC
6 changed files with 673 additions and 237 deletions

View file

@ -1,6 +1,5 @@
use std::collections::HashMap;
use crate::enviroment;
use std::{collections::HashMap, process, vec};
use crate::{enviroment, errors::{create_error, print_error, ErrorSubType, ErrorType}, Context};
const ASXVERSION: [u8; 3] = [0,1,0];
@ -68,6 +67,7 @@ struct DecompiledOperation {
arg1: u8,
arg2: i64,
arg3: u8,
pos: usize,
}
#[derive(Debug, Clone)]
@ -96,7 +96,8 @@ pub struct Machine {
pub stack: Vec<VMMemory>,
pub registers: Vec<Register>,
pub call_stack: Vec<CallStack>,
pub env: HashMap<String, VMMemory>
pub env: HashMap<String, VMMemory>,
pub ctx: Vec<Context>,
}
fn read_be_num(input: &[u8]) -> usize {
@ -228,18 +229,22 @@ fn get_mem_tbl_val(tbl: &VMMemoryTable, key: VMMemory) -> Option<&VMMemory> {
None
}
fn do_operation_operation(registers: &mut Vec<Register>, memory: &mut Vec<VMMemory>, operation: &DecompiledOperation) {
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);
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() {
panic!("One or more registers not found for operation");
let err = create_error(&format!("One or more registers not found for operation"), operation.pos, ErrorType::MachineError, ErrorSubType::RegisterNotFound);
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 {
panic!("Memory location out of bounds for registers {} and {}", operation.arg1, operation.arg2);
let err = create_error(&format!("Memory location out of bounds `{}` or `{}`", mem1, mem2), operation.pos, ErrorType::MachineError, ErrorSubType::MemoryOutOfBounds);
print_error(&err, &ctx);
process::exit(1);
}
let mut result: VMMemory;
match (&memory[mem1], &memory[mem2]) {
@ -256,7 +261,9 @@ fn do_operation_operation(registers: &mut Vec<Register>, memory: &mut Vec<VMMemo
},
13 => {
if num2.value == 0 {
panic!("Division by zero");
let err = create_error(&format!("Division by zero"), operation.pos, ErrorType::MathError, ErrorSubType::DivisionByZero);
print_error(&err, &ctx);
process::exit(1);
}
result = VMMemory::Number(VMMemoryNumber { value: num1.value / num2.value, variable_id: 0 });
},
@ -285,7 +292,9 @@ fn do_operation_operation(registers: &mut Vec<Register>, memory: &mut Vec<VMMemo
result = VMMemory::Boolean(VMMemoryBoolean { value: num1.value <= num2.value, variable_id: 0 });
},
_ => {
panic!("Unknown operation code for number operation: {}", operation.opcode);
let err = create_error(&format!("Unknown operation code for number operation: `{}`", operation.opcode), operation.pos, ErrorType::MachineError, ErrorSubType::UnknownOPCode);
print_error(&err, &ctx);
process::exit(1);
}
};
},
@ -301,7 +310,9 @@ fn do_operation_operation(registers: &mut Vec<Register>, memory: &mut Vec<VMMemo
result = VMMemory::Boolean(VMMemoryBoolean { value: str1.value != str2.value, variable_id: 0 });
},
_ => {
panic!("Unknown operation code for string operation: {}", operation.opcode);
let err = create_error(&format!("Unknown operation code for string operation: `{}`", operation.opcode), operation.pos, ErrorType::MachineError, ErrorSubType::UnknownOPCode);
print_error(&err, &ctx);
process::exit(1);
}
};
},
@ -320,7 +331,9 @@ fn do_operation_operation(registers: &mut Vec<Register>, memory: &mut Vec<VMMemo
result = VMMemory::Boolean(VMMemoryBoolean { value: bool1.value != bool2.value, variable_id: 0 });
},
_ => {
panic!("Unknown operation code for boolean operation: {}", operation.opcode);
let err = create_error(&format!("Unknown operation code for boolean operation: `{}`", operation.opcode), operation.pos, ErrorType::MachineError, ErrorSubType::UnknownOPCode);
print_error(&err, &ctx);
process::exit(1);
}
};
},
@ -333,12 +346,16 @@ fn do_operation_operation(registers: &mut Vec<Register>, memory: &mut Vec<VMMemo
result = VMMemory::Boolean(VMMemoryBoolean { value: false, variable_id: 0 });
},
_ => {
panic!("Unknown operation code for null operation: {}", operation.opcode);
let err = create_error(&format!("Unknown operation code for null operation: `{}`", operation.opcode), operation.pos, ErrorType::MachineError, ErrorSubType::UnknownOPCode);
print_error(&err, &ctx);
process::exit(1);
}
};
},
_ => {
panic!("Invalid memory types for operation: {} and {}", mem1, mem2);
let err = create_error(&format!("Invalid memory types for operation: `{}` and `{}`", mem1, mem2), operation.pos, ErrorType::TypeError, ErrorSubType::InvalidType);
print_error(&err, &ctx);
process::exit(1);
}
}
let mut reg3_pointer = reg3.unwrap().pointer;
@ -431,11 +448,14 @@ fn load_func(data: Vec<u8>, offset: &mut usize) -> DecompiledFunction {
let arg1 = bin_to_num(op[5..9].to_string());
let arg2 = bin_to_snum(op[9..73].to_string());
let arg3 = bin_to_num(op[73..77].to_string());
let pos = read_be_num(&data[*offset..*offset + 4]);
*offset += 4;
body.push(DecompiledOperation {
opcode: op_code as u8,
arg1: arg1 as u8,
arg2: arg2,
arg3: arg3 as u8,
pos: pos,
});
}
println!("Variables: {:?}", variables);
@ -450,7 +470,7 @@ fn load_func(data: Vec<u8>, offset: &mut usize) -> DecompiledFunction {
}
impl Machine {
pub fn new() -> Self {
pub fn new(ctx: Vec<Context>) -> Self {
let mut registers = Vec::new();
for i in 0..17 {
registers.push(Register {
@ -470,7 +490,8 @@ impl Machine {
return_reg: 0,
pc: 0,
}],
env: enviroment::generate()
env: enviroment::generate(),
ctx: ctx,
};
}
@ -481,6 +502,7 @@ impl Machine {
if data[3..6] != ASXVERSION {
panic!("Unsupported ASX version");
}
let _func_count = read_be_num(&data[6..10]);
let mut offset = 6;
while offset < data.len() {
let func = load_func(data.clone(), &mut offset);
@ -494,11 +516,13 @@ impl Machine {
}
let func_clone = self.functions.clone();
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() {
panic!("Current function not found!");
let err = create_error(&format!("Current function not found"), 0, ErrorType::MachineError, ErrorSubType::UnknownFunction);
print_error(&err, &self.ctx[self.call_stack[executed_stack].func].clone());
process::exit(1);
}
let mut executed_func = executed_func.unwrap();
let mut executed_stack = self.call_stack.len()-1;
while self.call_stack[executed_stack].pc < executed_func.body.len() {
let operation = &executed_func.body[self.call_stack[executed_stack].pc];
self.call_stack[executed_stack].pc += 1;
@ -511,7 +535,9 @@ impl Machine {
//LDS
let str = executed_func.strings.get(&(operation.arg2 as u32));
if str.is_none() {
panic!("String with ID {} not found", operation.arg2);
let err = create_error(&format!("String with ID `{}` not found", operation.arg2), 0, ErrorType::MachineError, ErrorSubType::UnknownString);
print_error(&err, &self.ctx[self.call_stack[executed_stack].func].clone());
process::exit(1);
}
let str = str.unwrap();
self.memory.push(VMMemory::String(VMMemoryString { value: str.clone(), variable_id: 0 }));
@ -521,11 +547,15 @@ impl Machine {
//LDM
let mem = get_mem_pos_by_var_id(&self.memory, operation.arg2 as u32);
if mem.is_none() {
panic!("Memory with variable ID {} not found", operation.arg2);
let err = create_error(&format!("Memory with variable ID `{}` not found", operation.arg2), 0, ErrorType::MachineError, ErrorSubType::UnknownMemoryLocation);
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 {
panic!("Memory location out of bounds for variable ID {}", operation.arg2);
let err = create_error(&format!("Memory location out of bounds for variable ID `{}`", operation.arg2), 0, ErrorType::MachineError, ErrorSubType::MemoryOutOfBounds);
print_error(&err, &self.ctx[self.call_stack[executed_stack].func].clone());
process::exit(1);
}
let mut nmem = self.memory[mem].clone();
match &mut nmem {
@ -568,12 +598,16 @@ impl Machine {
//LDF
let func_pos = executed_func.functions.get(&(operation.arg2 as u32));
if func_pos.is_none() {
panic!("Function with ID {} not found", operation.arg2);
let err = create_error(&format!("Function with ID `{}` not found", operation.arg2), 0, ErrorType::MachineError, ErrorSubType::UnknownFunction);
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() {
panic!("Function with position {} not found", func_pos);
let err = create_error(&format!("Function with position `{}` not found", func_pos), 0, ErrorType::MachineError, ErrorSubType::UnknownFunction);
print_error(&err, &self.ctx[self.call_stack[executed_stack].func].clone());
process::exit(1);
}
self.memory.push(VMMemory::Function(VMMemoryFunction {
id: *func_pos as usize,
@ -595,11 +629,15 @@ impl Machine {
//ASS
let reg = get_register_by_id(&self.registers, operation.arg1);
if reg.is_none() {
panic!("Register {} not found", operation.arg1);
let err = create_error(&format!("Register `{}` not found", operation.arg1), 0, ErrorType::MachineError, ErrorSubType::RegisterNotFound);
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 {
panic!("Register {} points to an invalid memory location", operation.arg1);
let err = create_error(&format!("Register `{}` points to an invalid memory location", operation.arg1), 0, ErrorType::MachineError, ErrorSubType::MemoryOutOfBounds);
print_error(&err, &self.ctx[self.call_stack[executed_stack].func].clone());
process::exit(1);
}
let used_var = get_mem_pos_by_var_id(&self.memory, operation.arg2 as u32);
if let Some(pos) = used_var {
@ -660,13 +698,15 @@ impl Machine {
let temp_regs = self.registers.clone();
let reg1 = get_register_by_id(&temp_regs, operation.arg1);
if reg1.is_none() {
panic!("Register {} not found", operation.arg1);
let err = create_error(&format!("Register `{}` not found", operation.arg1), 0, ErrorType::MachineError, ErrorSubType::RegisterNotFound);
print_error(&err, &self.ctx[self.call_stack[executed_stack].func].clone());
process::exit(1);
}
let reg1 = reg1.unwrap();
set_register(&mut self.registers, Register { id: operation.arg2 as u8, pointer: reg1.pointer });
},
10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 => {
do_operation_operation(&mut self.registers, &mut self.memory, operation);
do_operation_operation(&mut self.registers, &mut self.memory, operation, &self.ctx[self.call_stack[executed_stack].func].clone());
},
24 => {
//NOT
@ -674,7 +714,9 @@ 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() {
panic!("One or more registers not found for operation");
let err = create_error(&format!("Register `{}` or `{}` not found", operation.arg1, operation.arg2), 0, ErrorType::MachineError, ErrorSubType::RegisterNotFound);
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 {
@ -737,7 +779,9 @@ impl Machine {
//CJP
let reg = get_register_by_id(&self.registers, operation.arg1);
if reg.is_none() {
panic!("Register {} not found", operation.arg1);
let err = create_error(&format!("Register `{}` not found", operation.arg1), 0, ErrorType::MachineError, ErrorSubType::RegisterNotFound);
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);
@ -758,7 +802,9 @@ impl Machine {
//CAL
let reg = get_register_by_id(&self.registers, operation.arg1);
if reg.is_none() {
panic!("Register {} doesn't exist", operation.arg1);
let err = create_error(&format!("Register `{}` not found", operation.arg1), 0, ErrorType::MachineError, ErrorSubType::RegisterNotFound);
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);
@ -818,7 +864,9 @@ impl Machine {
//PSH
let reg = get_register_by_id(&self.registers, operation.arg1);
if reg.is_none() {
panic!("Register {} not found", operation.arg1);
let err = create_error(&format!("Register `{}` not found", operation.arg1), 0, ErrorType::MachineError, ErrorSubType::RegisterNotFound);
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);
@ -833,7 +881,9 @@ 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() {
panic!("Return register or target register not found");
let err = create_error(&format!("Register `{}` or `{}` not found", self.call_stack[executed_stack].return_reg, operation.arg1), 0, ErrorType::MachineError, ErrorSubType::RegisterNotFound);
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() {
@ -859,7 +909,9 @@ 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() {
panic!("One or more registers not found for GET operation");
let err = create_error(&format!("Register `{}` or `{}` not found", operation.arg2, operation.arg3), 0, ErrorType::MachineError, ErrorSubType::RegisterNotFound);
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() {
@ -925,7 +977,9 @@ 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() {
panic!("One or more registers not found for SET operation");
let err = create_error(&format!("Register `{}` or `{}` or `{}` not found", operation.arg1, operation.arg2, operation.arg3), 0, ErrorType::MachineError, ErrorSubType::RegisterNotFound);
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);
@ -994,7 +1048,9 @@ 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() {
panic!("One or more registers not found for SET operation");
let err = create_error(&format!("Register `{}` or `{}` or `{}` not found", operation.arg1, operation.arg2, operation.arg3), 0, ErrorType::MachineError, ErrorSubType::RegisterNotFound);
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);
@ -1015,7 +1071,9 @@ impl Machine {
}
},
_ => {
panic!("Unknown operation code: {}", operation.opcode);
let err = create_error(&format!("Unknown operation code: `{}`", operation.opcode), 0, ErrorType::MachineError, ErrorSubType::UnknownOPCode);
print_error(&err, &self.ctx[self.call_stack[executed_stack].func].clone());
process::exit(1);
}
}
}