compiler is pretty much done

This commit is contained in:
afonya2 2025-06-01 14:37:46 +02:00
parent 44a455f542
commit 2894780124
Signed by: afonya
GPG key ID: EBB9C4CAFAAFB2DC
3 changed files with 101 additions and 3 deletions

View file

@ -1,7 +1,9 @@
use std::{collections::HashMap};
use std::collections::HashMap;
use crate::parser::ASTPart;
const ASXVERSION: [u8; 3] = [0,1,0];
#[derive(Debug, Clone)]
pub struct Operation {
pub opcode: u8,
@ -525,6 +527,51 @@ fn compile_function(ast: Vec<ASTPart>, args: Option<Vec<String>>, registers: &mu
};
}
fn append_be_num(output: &mut Vec<u8>, size: usize, num: usize) { //appends a big-endian u number to the output
for i in (0..size).rev() {
output.push(((num >> (i * 8)) & 0xFF) as u8);
}
}
fn append_string(output: &mut Vec<u8>, input: String, add_len: bool) {
let bytes = input.as_bytes();
if add_len {
append_be_num(output, 4, bytes.len());
}
output.extend_from_slice(bytes);
}
fn append_binary(output: &mut Vec<u8>, input: String) {
let mut inp = input.clone();
while inp.len() >= 8 {
let byte = bin_to_num(inp[..8].to_string());
output.push(byte as u8);
inp = inp[8..].to_string();
}
}
fn num_to_bin(number: usize, size: usize) -> String {
let mut bin = String::new();
for i in (0..size).rev() {
if (number >> i) & 1 == 1 {
bin.push('1');
} else {
bin.push('0');
}
}
return bin;
}
fn bin_to_num(bin: String) -> usize {
let mut num = 0;
for (i, c) in bin.chars().rev().enumerate() {
if c == '1' {
num += 1 << i;
}
}
return num;
}
pub fn compile(ast: Vec<ASTPart>) -> Vec<u8> {
let mut registers: Vec<RegisterState> = vec![];
for i in 0..17 {
@ -539,5 +586,55 @@ pub fn compile(ast: Vec<ASTPart>) -> Vec<u8> {
let compiled = compile_function(ast, None, &mut registers);
println!("Compiled: {:?}", compiled);
return vec![];
let mut output: Vec<u8> = vec![];
//doctype specifier
append_string(&mut output, String::from("ASX"), false);
//version
output.push(ASXVERSION[0]);
output.push(ASXVERSION[1]);
output.push(ASXVERSION[2]);
//file name
append_string(&mut output, String::from("main.asl"), true);
//function
append_string(&mut output, String::from("main"), true);
//function headers
append_be_num(&mut output, 4, compiled.var_ids.len());
for var_id in compiled.var_ids.keys() {
append_string(&mut output, var_id.clone(), true);
append_be_num(&mut output, 3, compiled.var_ids[var_id] as usize);
}
append_be_num(&mut output, 4, compiled.strings.len());
for strs in compiled.strings.keys() {
append_be_num(&mut output, 3, *strs as usize);
append_string(&mut output, compiled.strings[strs].clone(), true);
}
append_be_num(&mut output, 4, 0);
/*for funcs in compiled.functions.keys() {
//not implemented yet
}*/
//function body
append_be_num(&mut output, 4, compiled.operations.len());
for ops in compiled.operations {
let mut op_bin = num_to_bin(ops.opcode.into(), 5);
if let Some(arg1) = ops.arg1 {
op_bin.push_str(&num_to_bin(arg1.into(), 4));
} else {
op_bin.push_str(&num_to_bin(0, 4));
}
if let Some(arg2) = ops.arg2 {
op_bin.push_str(&num_to_bin(arg2 as usize, 64));
} else {
op_bin.push_str(&num_to_bin(0, 64));
}
if let Some(arg3) = ops.arg3 {
op_bin.push_str(&num_to_bin(arg3.into(), 4));
} else {
op_bin.push_str(&num_to_bin(0, 4));
}
op_bin.push_str(&num_to_bin(0, 3));
println!("{}", op_bin);
append_binary(&mut output, op_bin);
}
return output;
}

View file

@ -125,6 +125,7 @@ fn main() {
}
let compiled = compiler::compile(ast);
println!("Compiled output: {:?}", compiled);
fs::write("./compiled.asx", compiled).expect("Failed to write compiled file");
/*let mut executor = Executor::new(ast, 100);
executor.resume();
println!("\nFinished!");

View file

@ -1 +1 @@
reti 1
gethelj a = 1