added some base operations to the VM

This commit is contained in:
afonya2 2025-06-01 15:54:48 +02:00
parent 3188361158
commit 3695f409db
Signed by: afonya
GPG key ID: EBB9C4CAFAAFB2DC
2 changed files with 123 additions and 12 deletions

View file

@ -130,6 +130,10 @@ fn main() {
println!("Compiled output: {:?}", compiled);
let mut vm = Machine::new();
vm.load(compiled);
vm.run();
println!("Registers: {:?}", vm.registers);
println!("Program Counter: {}", vm.pc);
println!("Memory: {:?}", vm.memory);
/*let mut executor = Executor::new(ast, 100);
executor.resume();
println!("\nFinished!");

View file

@ -2,32 +2,40 @@ use std::collections::HashMap;
const ASXVERSION: [u8; 3] = [0,1,0];
enum VMMemory {
#[derive(Debug, Clone)]
pub enum VMMemory {
String(VMMemoryString),
Number(VMMemoryNumber),
Boolean(VMMemoryBoolean),
Null,
Null(VMMemoryNull),
}
#[derive(Debug, Clone)]
struct VMMemoryString {
value: String,
variable_id: u32,
}
#[derive(Debug, Clone)]
struct VMMemoryNumber {
value: i64,
variable_id: u32,
}
#[derive(Debug, Clone)]
struct VMMemoryBoolean {
value: bool,
variable_id: u32,
}
#[derive(Debug, Clone)]
struct VMMemoryNull {
variable_id: u32,
}
#[derive(Debug)]
#[derive(Debug, Clone)]
struct DecompiledFile {
name: String,
functions: Vec<DecompiledFunction>,
}
#[derive(Debug)]
#[derive(Debug, Clone)]
struct DecompiledFunction {
name: String,
body: Vec<DecompiledOperation>,
@ -35,7 +43,7 @@ struct DecompiledFunction {
strings: HashMap<u32, String>,
functions: HashMap<u32, u32>
}
#[derive(Debug)]
#[derive(Debug, Clone)]
struct DecompiledOperation {
opcode: u8,
arg1: u8,
@ -44,17 +52,17 @@ struct DecompiledOperation {
}
#[derive(Debug)]
struct Register {
pub struct Register {
id: u8,
pointer: usize
}
pub struct Machine {
memory: Vec<VMMemory>,
files: Vec<DecompiledFile>,
stack: Vec<VMMemory>,
registers: Vec<Register>,
pc: usize,
pub memory: Vec<VMMemory>,
pub files: Vec<DecompiledFile>,
pub stack: Vec<VMMemory>,
pub registers: Vec<Register>,
pub pc: usize,
}
fn read_be_num(input: &[u8]) -> usize {
@ -110,6 +118,45 @@ 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 {
return Some(reg);
}
}
None
}
fn set_register(registers: &mut Vec<Register>, new_register: Register) {
if new_register.id == 0 {
return;
}
for (i, reg) in registers.iter().enumerate() {
if reg.id == new_register.id {
registers[i] = new_register;
return;
}
}
}
impl Machine {
pub fn new() -> Self {
let mut registers = Vec::new();
@ -120,7 +167,9 @@ impl Machine {
});
}
return Machine {
memory: Vec::new(),
memory: vec![
VMMemory::Null(VMMemoryNull { variable_id: 0 })
],
files: Vec::new(),
stack: Vec::new(),
registers: registers,
@ -202,4 +251,62 @@ impl Machine {
});
println!("Decompiled: {:?}", self.files[0]);
}
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_func = get_function_by_name(&main.unwrap(), "main");
if main_func.is_none() {
panic!("Main function not found");
}
let main_func = main_func.unwrap();
while self.pc < main_func.body.len() {
let operation = &main_func.body[self.pc];
self.pc += 1;
match operation.opcode {
0 => {
//HLT
return;
},
3 => {
//LDI
self.memory.push(VMMemory::Number(VMMemoryNumber { value: operation.arg2, variable_id: 0 }));
set_register(&mut self.registers, Register { id: operation.arg1, pointer: self.memory.len() - 1 });
},
7 => {
//ASS
let reg = get_register_by_id(&self.registers, operation.arg1);
if reg.is_none() {
panic!("Register {} not found", operation.arg1);
}
let reg = reg.unwrap();
if reg.pointer >= self.memory.len() || reg.pointer < 1 {
panic!("Register {} points to an invalid memory location", operation.arg1);
}
match &mut self.memory[reg.pointer] {
VMMemory::Number(num) => {
num.variable_id = operation.arg2 as u32;
},
VMMemory::String(str) => {
str.variable_id = operation.arg2 as u32;
},
VMMemory::Boolean(bool) => {
bool.variable_id = operation.arg2 as u32;
},
VMMemory::Null(null) => {
null.variable_id = operation.arg2 as u32;
},
}
},
29 => {
//RET
//not implemented yet
},
_ => panic!("Unknown opcode: {}", main_func.body[self.pc].opcode),
}
}
}
}