from-scratch/lang/tests/codegen.rs
2025-11-03 17:04:11 +01:00

102 lines
2.8 KiB
Rust

#![feature(debug_closure_helpers)]
#[path = "shared/shared.rs"]
mod util;
#[path = "shared/ast_debug.rs"]
mod ast_debug;
use util::defs::{parse_func, Ast, AstNode};
unsafe extern "C" {
unsafe fn bump_init();
unsafe fn tokeniser_init_buf(bytes: *const u8, len: usize) -> ();
}
fn main() {
unsafe {
bump_init();
}
println!("Bump allocator initialized.");
unsafe {
let mut buf = [0u8; 4];
assert_eq!(
util::defs::get_register_name(0, 4, buf.as_mut_ptr()).as_str(),
"eax"
);
assert_eq!(
util::defs::get_register_name(7, 8, buf.as_mut_ptr()).as_str(),
"rsp"
);
assert_eq!(
util::defs::get_register_name(7, 4, buf.as_mut_ptr()).as_str(),
"esp"
);
assert_eq!(
util::defs::get_register_name(7, 2, buf.as_mut_ptr()).as_str(),
"sp"
);
assert_eq!(
util::defs::get_register_name(7, 1, buf.as_mut_ptr()).as_str(),
"spl"
);
assert_eq!(
util::defs::get_register_name(9, 1, buf.as_mut_ptr()).as_str(),
"r9b"
);
assert_eq!(
util::defs::get_register_name(12, 1, buf.as_mut_ptr()).as_str(),
"r12b"
);
assert_eq!(
util::defs::get_register_name(12, 4, buf.as_mut_ptr()).as_str(),
"r12d"
);
assert_eq!(
util::defs::get_register_name(8, 2, buf.as_mut_ptr()).as_str(),
"r8w"
);
}
fn print_ast(src: &[u8], parser: impl FnOnce(&mut Ast) -> u64) {
unsafe {
tokeniser_init_buf(src.as_ptr(), src.len());
let mut ast = Ast {
nodes: util::vec::Vec::new(),
};
let expr_id = parser(&mut ast);
eprintln!("{}", core::str::from_utf8_unchecked(src));
eprintln!("Parsed expression ID: {}", expr_id);
let mut symtable = core::mem::MaybeUninit::<util::defs::SymbolTable>::uninit();
util::defs::ast_build_symtable(&mut ast, expr_id, &mut symtable);
let mut symtable = symtable.assume_init();
util::defs::ast_resolve_var_refs(&mut ast, &mut symtable, expr_id);
println!("{:#}", &ast);
let mut codegen = util::defs::CodegenCtx {
ast: &mut ast,
text: util::vec::Vec::new_with(1024),
};
util::defs::codegen_function(&mut codegen, expr_id);
eprintln!("Code generation completed.");
println!(
"Generated code:\n{}",
core::str::from_utf8_unchecked(codegen.text.as_slice())
);
};
}
print_ast(
b"fn main(a: u32) -> void {
let b: *u32 = &a;
return 5 + *b;
}",
|ast| unsafe { parse_func(ast) },
);
}