This commit is contained in:
afonya2 2025-06-01 15:33:42 +02:00
parent 2894780124
commit 3188361158
Signed by: afonya
GPG key ID: EBB9C4CAFAAFB2DC
2 changed files with 210 additions and 1 deletions

View file

@ -2,12 +2,15 @@ use std::fs;
use executor::Executor; use executor::Executor;
use parser::ASTPart; use parser::ASTPart;
use virtualmachine::Machine;
mod lexer; mod lexer;
mod parser; mod parser;
mod executor; mod executor;
mod enviroment; mod enviroment;
mod compiler; mod compiler;
mod virtualmachine;
fn log_ast_part(part: &ASTPart, prefix: String) { fn log_ast_part(part: &ASTPart, prefix: String) {
match part { match part {
@ -125,7 +128,8 @@ fn main() {
} }
let compiled = compiler::compile(ast); let compiled = compiler::compile(ast);
println!("Compiled output: {:?}", compiled); println!("Compiled output: {:?}", compiled);
fs::write("./compiled.asx", compiled).expect("Failed to write compiled file"); let mut vm = Machine::new();
vm.load(compiled);
/*let mut executor = Executor::new(ast, 100); /*let mut executor = Executor::new(ast, 100);
executor.resume(); executor.resume();
println!("\nFinished!"); println!("\nFinished!");

205
src/virtualmachine.rs Normal file
View file

@ -0,0 +1,205 @@
use std::collections::HashMap;
const ASXVERSION: [u8; 3] = [0,1,0];
enum VMMemory {
String(VMMemoryString),
Number(VMMemoryNumber),
Boolean(VMMemoryBoolean),
Null,
}
struct VMMemoryString {
value: String,
variable_id: u32,
}
struct VMMemoryNumber {
value: i64,
variable_id: u32,
}
struct VMMemoryBoolean {
value: bool,
variable_id: u32,
}
#[derive(Debug)]
struct DecompiledFile {
name: String,
functions: Vec<DecompiledFunction>,
}
#[derive(Debug)]
struct DecompiledFunction {
name: String,
body: Vec<DecompiledOperation>,
var_ids: HashMap<String, u32>,
strings: HashMap<u32, String>,
functions: HashMap<u32, u32>
}
#[derive(Debug)]
struct DecompiledOperation {
opcode: u8,
arg1: u8,
arg2: i64,
arg3: u8,
}
#[derive(Debug)]
struct Register {
id: u8,
pointer: usize
}
pub struct Machine {
memory: Vec<VMMemory>,
files: Vec<DecompiledFile>,
stack: Vec<VMMemory>,
registers: Vec<Register>,
pc: usize,
}
fn read_be_num(input: &[u8]) -> usize {
let mut result: usize = 0;
for i in 0..input.len() {
result <<= 8;
result |= input[i] as usize;
}
return result;
}
fn read_str(input: &[u8]) -> String {
let mut result = String::new();
for &byte in input {
result.push(byte as char);
}
return result;
}
fn read_bin(input: &[u8]) -> String {
let mut result = String::new();
for &byte in input {
result.push_str(&format!("{:08b}", byte));
}
return result;
}
fn bin_to_num(bin: String) -> usize {
let mut result: usize = 0;
for (i, c) in bin.chars().rev().enumerate() {
if c == '1' {
result += 1 << i;
}
}
return result;
}
fn bin_to_snum(bin: String) -> i64 {
let mut result: i64 = 0;
let mut is_negative = false;
for (i, c) in bin.chars().rev().enumerate() {
if c == '1' {
if i == bin.len() - 1 {
is_negative = true;
} else {
result += 1 << i;
}
}
}
if is_negative {
result = -result;
}
return result;
}
impl Machine {
pub fn new() -> Self {
let mut registers = Vec::new();
for i in 1..17 {
registers.push(Register {
id: i,
pointer: 0,
});
}
return Machine {
memory: Vec::new(),
files: Vec::new(),
stack: Vec::new(),
registers: registers,
pc: 0,
};
}
pub fn load(&mut self, data: Vec<u8>) {
if data[0..3] != *"ASX".as_bytes() {
panic!("Invalid ASX file header");
}
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 var_ids: HashMap<String, u32> = HashMap::new();
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;
var_ids.insert(name, var_id);
}
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, var_ids: var_ids, strings: strings, functions: functions });
self.files.push(DecompiledFile {
name: filename,
functions: file_functions
});
println!("Decompiled: {:?}", self.files[0]);
}
}