added function to the ASX standard

This commit is contained in:
afonya2 2025-06-03 17:43:03 +02:00
parent a8e174af7f
commit 598f4a0cdb
Signed by: afonya
GPG key ID: EBB9C4CAFAAFB2DC
3 changed files with 126 additions and 136 deletions

View file

@ -28,7 +28,7 @@ pub struct VMMemoryBoolean {
}
#[derive(Debug, Clone)]
pub struct VMMemoryFunction {
pub function: DecompiledFunction,
function: DecompiledFunction,
pub variable_id: u32,
}
#[derive(Debug, Clone)]
@ -36,14 +36,8 @@ pub struct VMMemoryNull {
pub variable_id: u32,
}
#[derive(Debug, Clone)]
struct DecompiledFile {
name: String,
functions: Vec<DecompiledFunction>,
}
#[derive(Debug, Clone)]
struct DecompiledFunction {
name: String,
body: Vec<DecompiledOperation>,
variables: Vec<Variable>,
strings: HashMap<u32, String>,
@ -73,7 +67,7 @@ struct Variable {
pub struct Machine {
pub memory: Vec<VMMemory>,
files: Vec<DecompiledFile>,
functions: Vec<DecompiledFunction>,
pub stack: Vec<VMMemory>,
pub registers: Vec<Register>,
pub pc: usize,
@ -132,24 +126,6 @@ fn bin_to_snum(bin: String) -> i64 {
return result;
}
fn get_file_by_name(files: &Vec<DecompiledFile>, name: &str) -> Option<DecompiledFile> {
for file in files {
if file.name == name {
return Some(file.clone());
}
}
None
}
fn get_function_by_name(file: &DecompiledFile, name: &str) -> Option<DecompiledFunction> {
for function in &file.functions {
if function.name == name {
return Some(function.clone());
}
}
None
}
fn get_register_by_id(registers: &Vec<Register>, id: u8) -> Option<&Register> {
for reg in registers {
if reg.id == id {
@ -334,6 +310,74 @@ fn do_operation_operation(registers: &mut Vec<Register>, memory: &mut Vec<VMMemo
memory[reg3_pointer] = result;
}
fn load_func(data: Vec<u8>, offset: &mut usize) -> DecompiledFunction {
let var_id_len = read_be_num(&data[*offset..*offset + 4]);
*offset += 4;
let mut variables: Vec<Variable> = vec![];
for _ in 0..var_id_len {
let name_len = read_be_num(&data[*offset..*offset + 4]);
*offset += 4;
let name = read_str(&data[*offset..*offset + name_len]);
*offset += name_len;
let var_id = read_be_num(&data[*offset..*offset + 3]) as u32;
*offset += 3;
let start = read_be_num(&data[*offset..*offset + 4]);
*offset += 4;
let end = read_be_num(&data[*offset..*offset + 4]);
*offset += 4;
variables.push(Variable { name: name, id: var_id, start: start, end: end });
}
let mut strings: HashMap<u32, String> = HashMap::new();
let string_count = read_be_num(&data[*offset..*offset + 4]);
*offset += 4;
for _ in 0..string_count {
let str_id = read_be_num(&data[*offset..*offset + 3]) as u32;
*offset += 3;
let str_len = read_be_num(&data[*offset..*offset + 4]);
*offset += 4;
let str_value = read_str(&data[*offset..*offset + str_len]);
*offset += str_len;
strings.insert(str_id, str_value);
}
let mut functions: HashMap<u32, u32> = HashMap::new();
let function_count = read_be_num(&data[*offset..*offset + 4]);
*offset += 4;
for _ in 0..function_count {
let func_id = read_be_num(&data[*offset..*offset + 3]) as u32;
*offset += 3;
let func_pos = read_be_num(&data[*offset..*offset + 4]) as u32;
*offset += 4;
functions.insert(func_id, func_pos);
}
println!("Variables: {:?}", variables);
println!("Strings: {:?}", strings);
println!("Functions: {:?}", functions);
let mut body: Vec<DecompiledOperation> = Vec::new();
let instr_len: usize = read_be_num(&data[*offset..*offset + 4]);
*offset += 4;
for _ in 0..instr_len {
let op = read_bin(&data[*offset..*offset + 10]);
*offset += 10;
println!("{}", op);
let op_code = bin_to_num(op[0..5].to_string());
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());
body.push(DecompiledOperation {
opcode: op_code as u8,
arg1: arg1 as u8,
arg2: arg2,
arg3: arg3 as u8,
});
}
return DecompiledFunction {
body: body,
variables: variables,
strings: strings,
functions: functions,
};
}
impl Machine {
pub fn new() -> Self {
let mut registers = Vec::new();
@ -347,7 +391,7 @@ impl Machine {
memory: vec![
VMMemory::Null(VMMemoryNull { variable_id: 0 })
],
files: Vec::new(),
functions: Vec::new(),
stack: Vec::new(),
registers: registers,
pc: 0,
@ -361,87 +405,18 @@ impl Machine {
if data[3..6] != ASXVERSION {
panic!("Unsupported ASX version");
}
let filename_len = read_be_num(&data[6..10]);
let filename = read_str(&data[10..10 + filename_len]);
let mut offset = 10 + filename_len;
let func_name_len = read_be_num(&data[offset..offset + 4]);
offset += 4;
let func_name = read_str(&data[offset..offset + func_name_len]);
offset += func_name_len;
let var_id_len = read_be_num(&data[offset..offset + 4]);
offset += 4;
let mut variables: Vec<Variable> = vec![];
for _ in 0..var_id_len {
let name_len = read_be_num(&data[offset..offset + 4]);
offset += 4;
let name = read_str(&data[offset..offset + name_len]);
offset += name_len;
let var_id = read_be_num(&data[offset..offset + 3]) as u32;
offset += 3;
let start = read_be_num(&data[offset..offset + 4]);
offset += 4;
let end = read_be_num(&data[offset..offset + 4]);
offset += 4;
variables.push(Variable { name: name, id: var_id, start: start, end: end });
let mut offset = 6;
while offset < data.len() {
let func = load_func(data.clone(), &mut offset);
self.functions.push(func);
}
let mut strings: HashMap<u32, String> = HashMap::new();
let string_count = read_be_num(&data[offset..offset + 4]);
offset += 4;
for _ in 0..string_count {
let str_id = read_be_num(&data[offset..offset + 3]) as u32;
offset += 3;
let str_len = read_be_num(&data[offset..offset + 4]);
offset += 4;
let str_value = read_str(&data[offset..offset + str_len]);
offset += str_len;
strings.insert(str_id, str_value);
}
let mut functions: HashMap<u32, u32> = HashMap::new();
let _function_count = read_be_num(&data[offset..offset + 4]);
offset += 4;
for _ in 0.._function_count {
let func_id = read_be_num(&data[offset..offset + 3]) as u32;
offset += 3;
let func_pos = read_be_num(&data[offset..offset + 4]) as u32;
offset += 4;
functions.insert(func_id, func_pos);
}
let mut body: Vec<DecompiledOperation> = Vec::new();
let instr_len: usize = read_be_num(&data[offset..offset + 4]);
offset += 4;
for _ in 0..instr_len {
let op = read_bin(&data[offset..offset + 10]);
offset += 10;
println!("{}", op);
let op_code = bin_to_num(op[0..5].to_string());
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());
body.push(DecompiledOperation {
opcode: op_code as u8,
arg1: arg1 as u8,
arg2: arg2,
arg3: arg3 as u8,
});
}
let mut file_functions: Vec<DecompiledFunction> = Vec::new();
file_functions.push(DecompiledFunction { name: func_name, body: body, variables: variables, strings: strings, functions: functions });
self.files.push(DecompiledFile {
name: filename,
functions: file_functions
});
println!("Decompiled: {:?}", self.files[0]);
println!("Decompiled: {:?}", self.functions);
}
pub fn run(&mut self) {
let main = get_file_by_name(&self.files, "main.asl");
if main.is_none() {
panic!("Main file not found");
}
let main = main.unwrap();
let main_func = get_function_by_name(&main, "main");
let main_func = self.functions.get(0);
if main_func.is_none() {
panic!("Main function not found");
panic!("No main function found!");
}
let main_func = main_func.unwrap();
while self.pc < main_func.body.len() {
@ -488,7 +463,7 @@ impl Machine {
panic!("Function with ID {} not found", operation.arg2);
}
let func_pos = func_pos.unwrap();
let func = main.functions.get(*func_pos as usize);
let func = self.functions.get(*func_pos as usize);
if func.is_none() {
panic!("Function with position {} not found", func_pos);
}