fixed multiple variable issues, added a way to view an ASX file
This commit is contained in:
parent
8f967fc172
commit
bf82ead8a8
4 changed files with 123 additions and 19 deletions
|
@ -1,7 +1,7 @@
|
|||
use std::{collections::HashMap, fs, process, vec};
|
||||
use crate::{errors::{create_error, print_error, ErrorSubType, ErrorType}, lexer::lex, parser::{parse, ASTPart}, Context};
|
||||
|
||||
const ASXVERSION: [u8; 3] = [0,1,0];
|
||||
const ASXVERSION: [u8; 3] = [0,2,0];
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Operation {
|
||||
|
@ -113,12 +113,12 @@ fn allocate_register(registers: &Vec<RegisterState>) -> AllocateResult {
|
|||
oldest_temp_register = register.id;
|
||||
}
|
||||
}
|
||||
if oldest_temp_register != 0 {
|
||||
/*if oldest_temp_register != 0 {
|
||||
return AllocateResult {
|
||||
register: oldest_temp_register,
|
||||
unbind_before: false,
|
||||
};
|
||||
}
|
||||
}*/
|
||||
return AllocateResult {
|
||||
register: oldest_register,
|
||||
unbind_before: true,
|
||||
|
@ -277,8 +277,12 @@ fn do_ast_op(ast_op: ASTPart, op_count: &mut usize, ops: &mut Vec<Operation>, va
|
|||
let op_placeholder = ops.len();
|
||||
ops.push(Operation { opcode: 0, arg1: None, arg2: None, arg3: None, pos: if_part.pos as u32 });
|
||||
let mut fake_vars: Vec<Variable> = vec![];
|
||||
let tb = PrevFunc {
|
||||
variables: variables.clone(),
|
||||
previous: Some(Box::new(traceback.clone())),
|
||||
};
|
||||
for if_op in if_part.body {
|
||||
do_ast_op(if_op, op_count, ops, &mut fake_vars, next_var_id, strings, next_string_id, functions, next_function_id, registers, ctx, traceback);
|
||||
do_ast_op(if_op, op_count, ops, &mut fake_vars, next_var_id, strings, next_string_id, functions, next_function_id, registers, ctx, &tb);
|
||||
}
|
||||
for fake_var in fake_vars {
|
||||
variables.push(Variable { name: fake_var.name, id: fake_var.id, start: fake_var.start, end: ops.len()-1, no_end: false });
|
||||
|
@ -321,9 +325,13 @@ fn do_ast_op(ast_op: ASTPart, op_count: &mut usize, ops: &mut Vec<Operation>, va
|
|||
|
||||
let op_placeholder = ops.len();
|
||||
ops.push(Operation { opcode: 0, arg1: None, arg2: None, arg3: None, pos: else_part.pos as u32 });
|
||||
let tb = PrevFunc {
|
||||
variables: variables.clone(),
|
||||
previous: Some(Box::new(traceback.clone())),
|
||||
};
|
||||
let mut fake_vars: Vec<Variable> = vec![];
|
||||
for else_op in else_part.body {
|
||||
do_ast_op(else_op, op_count, ops, &mut fake_vars, next_var_id, strings, next_string_id, functions, next_function_id, registers, ctx, traceback);
|
||||
do_ast_op(else_op, op_count, ops, &mut fake_vars, next_var_id, strings, next_string_id, functions, next_function_id, registers, ctx, &tb);
|
||||
}
|
||||
for fake_var in fake_vars {
|
||||
variables.push(Variable { name: fake_var.name, id: fake_var.id, start: fake_var.start, end: ops.len()-1, no_end: false });
|
||||
|
@ -373,9 +381,13 @@ fn do_ast_op(ast_op: ASTPart, op_count: &mut usize, ops: &mut Vec<Operation>, va
|
|||
|
||||
let op_placeholder = ops.len();
|
||||
ops.push(Operation { opcode: 0, arg1: None, arg2: None, arg3: None, pos: elseif_part.pos as u32 });
|
||||
let tb = PrevFunc {
|
||||
variables: variables.clone(),
|
||||
previous: Some(Box::new(traceback.clone())),
|
||||
};
|
||||
let mut fake_vars: Vec<Variable> = vec![];
|
||||
for elseif_op in elseif_part.body {
|
||||
do_ast_op(elseif_op, op_count, ops, &mut fake_vars, next_var_id, strings, next_string_id, functions, next_function_id, registers, ctx, traceback);
|
||||
do_ast_op(elseif_op, op_count, ops, &mut fake_vars, next_var_id, strings, next_string_id, functions, next_function_id, registers, ctx, &tb);
|
||||
}
|
||||
for fake_var in fake_vars {
|
||||
variables.push(Variable { name: fake_var.name, id: fake_var.id, start: fake_var.start, end: ops.len()-1, no_end: false });
|
||||
|
@ -403,6 +415,11 @@ fn do_ast_op(ast_op: ASTPart, op_count: &mut usize, ops: &mut Vec<Operation>, va
|
|||
let mut breaks: Vec<usize> = vec![];
|
||||
let mut continues: Vec<usize> = vec![];
|
||||
ops.push(Operation { opcode: 0, arg1: None, arg2: None, arg3: None, pos: while_part.pos as u32 });
|
||||
let tb = PrevFunc {
|
||||
variables: variables.clone(),
|
||||
previous: Some(Box::new(traceback.clone())),
|
||||
};
|
||||
let mut fake_vars: Vec<Variable> = vec![];
|
||||
for while_op in while_part.body {
|
||||
match while_op {
|
||||
ASTPart::Break(_) => {
|
||||
|
@ -414,10 +431,13 @@ fn do_ast_op(ast_op: ASTPart, op_count: &mut usize, ops: &mut Vec<Operation>, va
|
|||
ops.push(Operation { opcode: 0, arg1: None, arg2: None, arg3: None, pos: while_part.pos as u32 });
|
||||
},
|
||||
_ => {
|
||||
do_ast_op(while_op, op_count, ops, variables, next_var_id, strings, next_string_id, functions, next_function_id, registers, ctx, traceback);
|
||||
do_ast_op(while_op, op_count, ops, &mut fake_vars, next_var_id, strings, next_string_id, functions, next_function_id, registers, ctx, &tb);
|
||||
}
|
||||
}
|
||||
}
|
||||
for fake_var in fake_vars {
|
||||
variables.push(Variable { name: fake_var.name, id: fake_var.id, start: fake_var.start, end: ops.len()-1, no_end: false });
|
||||
}
|
||||
ops.push(Operation { opcode: 25, arg1: None, arg2: Some(start as f64), arg3: None, pos: while_part.pos as u32 });
|
||||
ops[op_placeholder] = Operation {
|
||||
opcode: 26,
|
||||
|
@ -465,6 +485,11 @@ fn do_ast_op(ast_op: ASTPart, op_count: &mut usize, ops: &mut Vec<Operation>, va
|
|||
let mut breaks: Vec<usize> = vec![];
|
||||
let mut continues: Vec<usize> = vec![];
|
||||
ops.push(Operation { opcode: 0, arg1: None, arg2: None, arg3: None, pos: for_part.pos as u32 });
|
||||
let tb = PrevFunc {
|
||||
variables: variables.clone(),
|
||||
previous: Some(Box::new(traceback.clone())),
|
||||
};
|
||||
let mut fake_vars: Vec<Variable> = vec![];
|
||||
for for_op in for_part.body {
|
||||
match for_op {
|
||||
ASTPart::Break(_) => {
|
||||
|
@ -476,10 +501,13 @@ fn do_ast_op(ast_op: ASTPart, op_count: &mut usize, ops: &mut Vec<Operation>, va
|
|||
ops.push(Operation { opcode: 0, arg1: None, arg2: None, arg3: None, pos: for_part.pos as u32 });
|
||||
},
|
||||
_ => {
|
||||
do_ast_op(for_op, op_count, ops, variables, next_var_id, strings, next_string_id, functions, next_function_id, registers, ctx, traceback);
|
||||
do_ast_op(for_op, op_count, ops, &mut fake_vars, next_var_id, strings, next_string_id, functions, next_function_id, registers, ctx, &tb);
|
||||
}
|
||||
}
|
||||
}
|
||||
for fake_var in fake_vars {
|
||||
variables.push(Variable { name: fake_var.name, id: fake_var.id, start: fake_var.start, end: ops.len()-1, no_end: false });
|
||||
}
|
||||
do_ast_op(*for_part.update, op_count, ops, variables, next_var_id, strings, next_string_id, functions, next_function_id, registers, ctx, traceback);
|
||||
|
||||
ops.push(Operation { opcode: 25, arg1: None, arg2: Some(start as f64), arg3: None, pos: for_part.pos as u32 });
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use std::collections::HashMap;
|
||||
|
||||
const ASXVERSION: [u8; 3] = [0,1,0];
|
||||
const ASXVERSION: [u8; 3] = [0,2,0];
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct DecompiledFunction {
|
||||
|
@ -26,9 +26,11 @@ pub struct Variable {
|
|||
pub end: usize
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct DecompiledData {
|
||||
pub functions: Vec<DecompiledFunction>,
|
||||
pub func_count: usize,
|
||||
pub version: String,
|
||||
}
|
||||
|
||||
pub fn operation_to_name(opcode: u8) -> String {
|
||||
|
@ -175,8 +177,10 @@ pub fn process(data: &Vec<u8>) -> DecompiledData {
|
|||
if data[0..3] != *"ASX".as_bytes() {
|
||||
panic!("Invalid ASX file header");
|
||||
}
|
||||
if data[3..6] != ASXVERSION {
|
||||
panic!("Unsupported ASX version");
|
||||
let ver = &data[3..6].to_vec();
|
||||
let ver_str: String = ver.iter().map(|b| b.to_string()).collect::<Vec<String>>().join(".");
|
||||
if *ver != ASXVERSION {
|
||||
panic!("Unsupported ASX version ({})", ver_str);
|
||||
}
|
||||
let func_count = read_be_num(&data[6..10]);
|
||||
let mut offset = 10;
|
||||
|
@ -188,5 +192,6 @@ pub fn process(data: &Vec<u8>) -> DecompiledData {
|
|||
return DecompiledData {
|
||||
functions: functions,
|
||||
func_count: func_count,
|
||||
version: ver_str,
|
||||
};
|
||||
}
|
63
src/main.rs
63
src/main.rs
|
@ -1,6 +1,6 @@
|
|||
use std::{env, fs, time::Instant};
|
||||
use virtualmachine::Machine;
|
||||
use crate::{decompiler::process, errors::{create_error, print_error, reverse_subtype_short, reverse_type_short}};
|
||||
use crate::{decompiler::{operation_to_name, process}, errors::{create_error, print_error, reverse_subtype_short, reverse_type_short}};
|
||||
|
||||
mod lexer;
|
||||
mod parser;
|
||||
|
@ -10,7 +10,7 @@ mod virtualmachine;
|
|||
mod errors;
|
||||
mod decompiler;
|
||||
|
||||
const CLIVER: [u8; 3] = [0, 1, 0];
|
||||
const CLIVER: [u8; 3] = [0, 2, 0];
|
||||
|
||||
#[derive(Clone)]
|
||||
struct Context {
|
||||
|
@ -26,6 +26,7 @@ fn print_help() {
|
|||
println!(" run - Run an ASL/ASX file");
|
||||
println!(" compile - Compile the ASL file to bytecode");
|
||||
println!(" traceback - Traceback an error based on an error code");
|
||||
println!(" viewx- - View the contents of an ASX file");
|
||||
}
|
||||
|
||||
fn main() {
|
||||
|
@ -158,6 +159,64 @@ fn main() {
|
|||
} else {
|
||||
println!("Unknown file type. Please use .asl files.");
|
||||
}
|
||||
} else if args[1] == "viewx" {
|
||||
let file = &args[2];
|
||||
if file.ends_with(".asx") {
|
||||
let inp = fs::read(file);
|
||||
match inp {
|
||||
Result::Ok(data) => {
|
||||
let decompiled = process(&data);
|
||||
println!("ASX Verion: {}", decompiled.version);
|
||||
println!("Function Count: {}", decompiled.func_count);
|
||||
for i in 0..decompiled.func_count {
|
||||
println!("Function {}:", i);
|
||||
let func = &decompiled.functions[i];
|
||||
println!(" Variables:");
|
||||
for var in &func.variables {
|
||||
println!(" {}: {} ({}:{})", var.id, var.name, var.start, var.end);
|
||||
}
|
||||
println!(" Strings:");
|
||||
for (id, string) in &func.strings {
|
||||
println!(" {}: {}", id, string);
|
||||
}
|
||||
println!(" Functions:");
|
||||
for (id, pos) in &func.functions {
|
||||
println!(" {}: {}", id, pos);
|
||||
}
|
||||
println!(" Body:");
|
||||
//Print these under each other like when you tabulate
|
||||
let mut longest_cols: Vec<usize> = vec![0, 0, 0, 0];
|
||||
for op in &func.body {
|
||||
longest_cols[0] = longest_cols[0].max(operation_to_name(op.opcode).len());
|
||||
longest_cols[1] = longest_cols[1].max(op.arg1.to_string().len());
|
||||
longest_cols[2] = longest_cols[2].max(op.arg2.to_string().len());
|
||||
longest_cols[3] = longest_cols[3].max(op.arg3.to_string().len());
|
||||
}
|
||||
let mut longest = 0;
|
||||
for op in &func.body {
|
||||
let op_name = operation_to_name(op.opcode);
|
||||
let str = format!(" {}{} {}{} {}{} {} at {}",
|
||||
op_name,
|
||||
" ".repeat(longest_cols[0] - op_name.len()),
|
||||
op.arg1,
|
||||
" ".repeat(longest_cols[1] - op.arg1.to_string().len()),
|
||||
op.arg2,
|
||||
" ".repeat(longest_cols[2] - op.arg2.to_string().len()),
|
||||
op.arg3,
|
||||
op.pos);
|
||||
longest = longest.max(str.len()+4);
|
||||
println!("{}", str);
|
||||
}
|
||||
println!("{}", "=".repeat(longest));
|
||||
}
|
||||
},
|
||||
Result::Err(err) => {
|
||||
panic!("Can't read file: {}", err);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
println!("Unknown file type. Please use .asx files.");
|
||||
}
|
||||
} else {
|
||||
println!("Invalid command.");
|
||||
print_help();
|
||||
|
|
24
test.asl
24
test.asl
|
@ -1,6 +1,18 @@
|
|||
gethelj a = -6.5
|
||||
ugass(nerd.abs(a))
|
||||
ugass(nerd.kerek(a, szaft"fel"szaft))
|
||||
ugass(nerd.sqrt(16))
|
||||
ugass(nerd.legnagyobb(3,56,66,1,12,55,6))
|
||||
ugass(nerd.legkisebb(3,56,66,1,12,55,6))
|
||||
gethelj a = 125
|
||||
gethelj b = 567
|
||||
gethelj c = 8765
|
||||
gethelj d = 123
|
||||
gethelj e = 123
|
||||
gethelj f = 123
|
||||
gethelj g = 123
|
||||
gethelj h = 123
|
||||
gethelj i = 123
|
||||
gethelj j = 123
|
||||
gethelj k = 123
|
||||
gethelj l = 123
|
||||
gethelj m = 123
|
||||
gethelj n = 123
|
||||
gethelj o = 123
|
||||
gethelj p = 123
|
||||
gethelj q = 123
|
||||
ugass(a+b+c)
|
Loading…
Add table
Add a link
Reference in a new issue