begin new error system, unfinished
This commit is contained in:
parent
32c2a20697
commit
532fffe725
6 changed files with 673 additions and 237 deletions
|
@ -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(®_clone, operation.arg1);
|
||||
let reg2 = get_register_by_id(®_clone, operation.arg2 as u8);
|
||||
let reg3 = get_register_by_id(®_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(®_clone, operation.arg1);
|
||||
let reg2 = get_register_by_id(®_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(®_clone, operation.arg2 as u8);
|
||||
let reg3 = get_register_by_id(®_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(®_clone, operation.arg2 as u8);
|
||||
let reg3 = get_register_by_id(®_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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue