Compare commits

...

9 commits

Author SHA1 Message Date
janis ea4611111b
remove strange file and print source in codegen test 2025-11-01 03:09:46 +01:00
janis 2ca60ace59
codegen working? pogU? 2025-11-01 03:01:48 +01:00
janis 105c052e95
more fixes for codegen 2025-11-01 02:50:39 +01:00
janis a25dcdabbb
many small fixes 2025-11-01 01:41:13 +01:00
janis e43424b780
fix int_to_str2 for 0 2025-11-01 01:41:05 +01:00
janis dae2e00569
fix vec_insert_many 2025-11-01 00:28:59 +01:00
janis 1adeca36ec
vec_insert_many 2025-11-01 00:08:44 +01:00
janis 9509931bc2
safety commit 2025-10-31 22:14:44 +01:00
janis d144537c3b
insert stackvar sorted 2025-10-31 17:19:19 +01:00
9 changed files with 1091 additions and 41 deletions

File diff suppressed because it is too large Load diff

View file

@ -104,7 +104,9 @@ int_to_str2:
test rdi, rdi test rdi, rdi
jnz .convert_loop jnz .convert_loop
mov byte [rsi + r12], '0' mov byte [rsi + r12], '0'
jmp .epilogue inc r13
inc r12
jmp .reverse
.convert_loop: .convert_loop:
mov rax, [rsp + 8] ; buffer length mov rax, [rsp + 8] ; buffer length
@ -129,6 +131,7 @@ int_to_str2:
test rdi, rdi test rdi, rdi
jnz .convert_loop jnz .convert_loop
.reverse:
; Reverse the digits ; Reverse the digits
mov rdx, r12 mov rdx, r12
dec r12 ; last digit index dec r12 ; last digit index

View file

@ -1 +0,0 @@
let fn if

View file

@ -23,6 +23,7 @@ global vec_get_or
global vec_drop global vec_drop
global vec_find global vec_find
global vec_insert global vec_insert
global vec_insert_many
global vec_insert_sorted global vec_insert_sorted
global vec_binary_search_by global vec_binary_search_by
@ -482,7 +483,7 @@ vec_find:
;; rdi: pointer to Vec struct ;; rdi: pointer to Vec struct
;; rsi : index ;; rsi : index
;; rdx: pointer to data to insert ;; rdx: pointer to data to insert
;; fn vec_insert(vec: *mut Vec, index: usize, data: *const T, size: usize) ;; fn vec_insert(vec: *mut Vec, index: usize, data: *const T)
vec_insert: vec_insert:
push rbp push rbp
mov rbp, rsp mov rbp, rsp
@ -530,6 +531,65 @@ vec_insert:
pop rbp pop rbp
ret ret
;; rdi: pointer to Vec struct
;; rsi : index
;; rdx: pointer to data to insert
;; rcx: count
;; define-fn: fn vec_insert_many(vec: *mut BlobVec, index: usize, data: *const u8, count: usize)
vec_insert_many:
push rbp
mov rbp, rsp
push r12
push rbx
sub rsp, 0x20
mov [rsp], rdi ; save vec
mov [rsp + 8], rsi ; save index
mov [rsp + 0x10], rdx ; save data ptr
mov [rsp + 0x18], rcx ; save count
mov rsi, [rdi + 8]
add rsi, rcx ; len + count
call vec_try_grow
mov rbx, [rsp] ; vec
mov rdi, [rbx] ; vec.data
mov rcx, [rbx + 24] ; item_size
mov rdx, [rbx + 8] ; len
sub rdx, [rsp + 8] ; len - index
mov rax, rdx
mul rcx ; (len - index) * item_size
mov r12, rax ; number of bytes to move
mov rsi, [rbx] ; vec.data
mov rax, [rsp + 8] ; index
mov rcx, [rbx + 24] ; item_size
mul rcx ; index * item_size
add rsi, rax ; src ptr
mov rdi, rsi
mov rax, [rsp + 0x18] ; count
mul rcx ; count * item_size
add rdi, rax ; dst ptr
mov rdx, r12 ; number of bytes to move
call memmove
mov rdi, rsi
mov rsi, [rsp + 0x10]
mov rcx, [rsp + 0x18] ; count
mov rax, [rbx + 24] ; item_size
mul rcx ; count * item_size
mov rdx, rax
call memcpy
mov rax, [rbx + 8] ; len
add rax, [rsp + 0x18] ; len += count
mov [rbx + 8], rax
add rsp, 32
pop rbx
pop r12
pop rbp
ret
;; rdi: pointer to Vec struct ;; rdi: pointer to Vec struct
;; rsi: pointer to key ;; rsi: pointer to key

View file

@ -66,6 +66,7 @@ fn main() {
nodes: util::vec::Vec::new(), nodes: util::vec::Vec::new(),
}; };
let expr_id = parser(&mut ast); let expr_id = parser(&mut ast);
eprintln!("{}", core::str::from_utf8_unchecked(src));
eprintln!("Parsed expression ID: {}", expr_id); eprintln!("Parsed expression ID: {}", expr_id);
let mut symtable = core::mem::MaybeUninit::<util::defs::SymbolTable>::uninit(); let mut symtable = core::mem::MaybeUninit::<util::defs::SymbolTable>::uninit();
util::defs::ast_build_symtable(&mut ast, expr_id, &mut symtable); util::defs::ast_build_symtable(&mut ast, expr_id, &mut symtable);
@ -76,27 +77,24 @@ fn main() {
let mut codegen = util::defs::CodegenCtx { let mut codegen = util::defs::CodegenCtx {
ast: &mut ast, ast: &mut ast,
text: util::vec::Vec::new(), text: util::vec::Vec::new_with(1024),
}; };
util::defs::codegen_function(&mut codegen, expr_id); util::defs::codegen_function(&mut codegen, expr_id);
eprintln!("Code generation completed.");
println!( println!(
"Generated code:\n{}", "Generated code:\n{}",
core::str::from_utf8(codegen.text.as_slice()).unwrap() core::str::from_utf8_unchecked(codegen.text.as_slice())
); );
}; };
} }
// print_ast( print_ast(
// b"fn main(a: u32) -> void { b"fn main(a: u32) -> void {
// let y: u32 = a + 4; return 4;
// { }",
// let y: u32 = 10; |ast| unsafe { parse_func(ast) },
// } );
// let y: *u32 = &y;
// return *y;
// }",
// |ast| unsafe { parse_func(ast) },
// );
} }

View file

@ -12,6 +12,11 @@ fn main() {
let value = 1234567890isize; let value = 1234567890isize;
let mut buffer = [0u8; 32]; let mut buffer = [0u8; 32];
unsafe { unsafe {
let slice = int_to_str2(0, buffer.as_mut_ptr(), buffer.len(), 10);
let s = slice.as_str();
println!("Integer: {}, String: {}", 0, s);
assert_eq!(s, format!("{}", 0));
let slice = int_to_str2(value, buffer.as_mut_ptr(), buffer.len(), 10); let slice = int_to_str2(value, buffer.as_mut_ptr(), buffer.len(), 10);
let s = slice.as_str(); let s = slice.as_str();
println!("Integer: {}, String: {}", value, s); println!("Integer: {}, String: {}", value, s);

View file

@ -19,7 +19,10 @@ unsafe extern "C" {
pub unsafe fn ast_resolve_var_refs(ast: *mut Ast, ctx: *mut SymbolTable, root_index: u64); pub unsafe fn ast_resolve_var_refs(ast: *mut Ast, ctx: *mut SymbolTable, root_index: u64);
pub unsafe fn get_register_name(reg_idx: u8, width: u8, buffer: *mut u8) -> FFISlice; pub unsafe fn get_register_name(reg_idx: u8, width: u8, buffer: *mut u8) -> FFISlice;
pub unsafe fn stackvar_cmp(a: *const (u64, u64), b: *const (u64, u64)) -> i32; pub unsafe fn stackvar_cmp(a: *const (u64, u64), b: *const (u64, u64)) -> i32;
pub unsafe fn codegen_allocate_register(ctx: *mut FunctionCtx) -> u8;
pub unsafe fn codegen_function(ast: *const CodegenCtx, func_idx: u64) -> (); pub unsafe fn codegen_function(ast: *const CodegenCtx, func_idx: u64) -> ();
pub unsafe fn codegen_expr(ctx: *const CodegenCtx, function_ctx: &FunctionCtx, expr_idx: u64) -> (u64, bool);
pub unsafe fn vec_insert_many(vec: *mut BlobVec, index: usize, data: *const u8, count: usize);
pub unsafe fn vec_extend(vec: *mut BlobVec, elements: *const u8, count: usize) -> (); pub unsafe fn vec_extend(vec: *mut BlobVec, elements: *const u8, count: usize) -> ();
} }
@ -50,6 +53,13 @@ pub const TYPE_I32: u8 = 3;
pub const TYPE_U32: u8 = 4; pub const TYPE_U32: u8 = 4;
pub const TYPE_STR: u8 = 5; pub const TYPE_STR: u8 = 5;
pub const TYPE_POINTER: u8 = 6; pub const TYPE_POINTER: u8 = 6;
pub const OPERAND_REGISTER: u32 = 1;
pub const OPERAND_RBP_OFFSET: u32 = 2;
pub const OPERAND_RSP_OFFSET: u32 = 3;
pub const OPERAND_ADDRESS: u32 = 4;
pub const OPERAND_IMMEDIATE: u32 = 5;
pub const OPERAND_CONSTANT: u32 = 6;
pub const OPERAND_LABEL: u32 = 7;
pub const TOKEN_EOF: u8 = 0; pub const TOKEN_EOF: u8 = 0;
pub const TOKEN_LET: u8 = 1; pub const TOKEN_LET: u8 = 1;
pub const TOKEN_IF: u8 = 2; pub const TOKEN_IF: u8 = 2;
@ -201,6 +211,24 @@ pub struct CodegenCtx {
pub text: Vec<u8>, pub text: Vec<u8>,
} }
#[repr(C)]
#[derive(Debug)]
pub struct FunctionCtx {
pub current_stack_size: u64,
pub stack_vars: Vec<(u64, u64)>,
pub register_bitset: u16,
pub dirtied_register_bitset: u16,
}
#[repr(C)]
#[derive(Debug)]
pub struct Operand {
pub kind: u8,
pub register_and_width: u8,
pub len: u16,
pub value: u64,
}
#[repr(C)] #[repr(C)]
#[derive(Debug)] #[derive(Debug)]
pub struct BlobVec { pub struct BlobVec {

View file

@ -160,6 +160,19 @@ pub mod vec {
} }
} }
pub fn insert_many(&mut self, index: usize, elements: Box<[T]>) {
unsafe {
let elements =
core::mem::transmute::<Box<[T]>, Box<[core::mem::ManuallyDrop<T>]>>(elements);
super::defs::vec_insert_many(
&mut self.vec,
index,
elements.as_ptr() as *const u8,
elements.len(),
);
}
}
pub fn pop(&mut self) -> Option<T> { pub fn pop(&mut self) -> Option<T> {
if self.vec.len == 0 { if self.vec.len == 0 {
return None; return None;

View file

@ -113,4 +113,9 @@ fn main() {
let elements = Box::new([1, 2, 3, 4, 5]); let elements = Box::new([1, 2, 3, 4, 5]);
vec.extend(elements); vec.extend(elements);
assert_eq!(vec.as_slice(), &[50, 1, 2, 3, 4, 5]); assert_eq!(vec.as_slice(), &[50, 1, 2, 3, 4, 5]);
// vec insert_many
let elements = Box::new([6, 7, 8]);
vec.insert_many(2, elements);
assert_eq!(vec.as_slice(), &[50, 1, 6, 7, 8, 2, 3, 4, 5]);
} }