ast: correctly resolves var refs

This commit is contained in:
janis 2025-10-31 01:55:04 +01:00
parent 935a3e0a53
commit e79af01925
Signed by: janis
SSH key fingerprint: SHA256:bB1qbbqmDXZNT0KKD5c2Dfjg53JGhj7B3CFcLIzSqq8
3 changed files with 83 additions and 60 deletions

View file

@ -68,6 +68,7 @@ global parse_statement
global parse_block global parse_block
global ast_build_symtable global ast_build_symtable
global ast_walk_for_each global ast_walk_for_each
global ast_resolve_var_refs
;; start very simple, with only functions and addition ;; start very simple, with only functions and addition
;; ```rust ;; ```rust
@ -1528,22 +1529,27 @@ ast_walk_for_each:
pop rbp pop rbp
ret ret
;; rdi: BuildSymtableCtx ;; rdi: *mut SymbolTable
;; rsi: *mut Ast ;; rsi: *mut Ast
;; rdx: node_index ;; rdx: node_index
;; rcx: scope
ast_resolve_var_refs_for_each: ast_resolve_var_refs_for_each:
push rbp push rbp
mov rbp, rsp mov rbp, rsp
push rbx push rbx
; lower_bound [88..96]
; scope: u64 [80..88]
; SymEntry [24..80] ; SymEntry [24..80]
; *AstNode [16..24] ; *AstNode [16..24]
; *BuildSymtableCtx [8..16] ; *BuildSymtableCtx [8..16]
; *Ast [0..8] ; *Ast [0..8]
sub rsp, 24 sub rsp, 96
mov [rsp], rsi ; Ast mov [rsp], rsi ; Ast
mov [rsp + 8], rdi ; Ctx mov [rsp + 8], rdi ; Ctx
mov [rsp + 80], rcx ; SymKey.scope_index
mov rdi, rsi ; Ast mov rdi, rsi ; Ast
mov rsi, rdx ; node_index mov rsi, rdx ; node_index
call vec_get call vec_get
@ -1556,45 +1562,59 @@ ast_resolve_var_refs_for_each:
; lookup variable in symbol table ; lookup variable in symbol table
; get current scope index ; binary search lower bound
mov qword [rsp + 32], 0 ; SymKey.scope_index = default mov byte [rsp + 24 + 0], SYM_KEY_START_LOCALS ; SymKey.kind
mov rdi, [rsp + 8] ; *Ctx mov qword [rsp + 24 + 8], 0 ; SymKey.scope_index
lea rdi, [rdi + 0] ; Ctx.scope_stack mov qword [rsp + 24 + 16], 0 ; SymKey.span
mov rsi, [rdi + 8] ; Ctx.scope_stack.len() mov qword [rsp + 24 + 24], 1 ; SymKey.name
dec rsi mov qword [rsp + 24 + 32], 0 ; SymKey.name_len
lea rdx, [rsp + 32]
call vec_get_or
mov rax, [rax] ; current scope index
; construct key
mov byte [rsp + 24 + 0], SYM_KEY_VAR ; SymKey.kind
mov [rsp + 24 + 8], rax ; SymKey.scope_index = scope_stack.last_or(0)
mov rax, [rsp + 16] ; *AstNode
mov rbx, [rax + 24] ; AstNode.span
mov [rsp + 24 + 16], rbx ; SymKey.span
mov rbx, [rax + 8] ; AstNode.data
mov rax, [rbx + 8] ; AstVarRef.name
mov rbx, [rbx + 16] ; AstVarRef.name_len
mov [rsp + 24 + 24], rax ; SymKey.ident
mov [rsp + 24 + 32], rbx ; SymKey.ident_len
; binary search in symbol table ; binary search in symbol table
mov rdi, [rsp + 8] ; *Ctx mov rdi, [rsp + 8] ; *Ctx
lea rdi, [rdi + 40] ; Ctx.symtable
lea rsi, [rsp + 24] ; &SymKey lea rsi, [rsp + 24] ; &SymKey
mov rdx, 0 ; cmp_ctx mov rdx, symkey_cmp ; cmp
mov rcx, symkey_cmp ; cmp mov rcx, 0 ; cmp_ctx
call vec_binary_search_by
mov [rsp + 88], rax ; lower_bound
; construct key
mov byte [rsp + 24 + 0], SYM_KEY_VAR ; SymKey.kind
mov rax, [rsp + 80] ; scope
mov [rsp + 24 + 8], rax ; SymKey.scope_index
mov rax, [rsp + 16] ; *AstNode
mov rbx, [rax + 24] ; AstNode.span
mov [rsp + 24 + 16], rbx ; SymKey.span
mov rbx, [rax + 8] ; AstNode.data
mov rax, [rbx + 8] ; AstVarRef.name
mov rbx, [rbx + 16] ; AstVarRef.name_len
mov [rsp + 24 + 24], rax ; SymKey.ident
mov [rsp + 24 + 32], rbx ; SymKey.ident_len
; binary search in symbol table
mov rdi, [rsp + 8] ; *Ctx
lea rsi, [rsp + 24] ; &SymKey
mov rdx, symkey_cmp ; cmp
mov rcx, 0 ; cmp_ctx
call vec_binary_search_by call vec_binary_search_by
test rdx, rdx test rdx, rdx
jnz .panic jz .fixup
dec rax
.fixup:
cmp rax, [rsp + 88] ; lower_bound
jl .panic
mov rdi, [rsp + 8] ; *Ctx
mov rsi, rax ; index
call vec_get
mov rax, [rax + 40] ; SymEntry.index
mov rdx, [rsp + 16] ; *AstNode mov rdx, [rsp + 16] ; *AstNode
mov rdx, [rdx + 8] ; AstNode.data mov rdx, [rdx + 8] ; AstNode.data
mov [rdx + 0], rax ; AstVarRef.resolved_index mov [rdx + 0], rax ; AstVarRef.resolved_index
.epilogue: .epilogue:
add rsp, 24 add rsp, 96
pop rbx pop rbx
pop rbp pop rbp
ret ret
@ -1602,18 +1622,17 @@ ast_resolve_var_refs_for_each:
call panic call panic
;; rdi: Ast ;; rdi: Ast
;; define-fn: fn ast_resolve_var_refs(ast: *mut Ast) ;; rsi: *mut SymbolTable
;; rdx: root_index
;; define-fn: fn ast_resolve_var_refs(ast: *mut Ast, ctx: *mut SymbolTable, root_index: u64)
ast_resolve_var_refs: ast_resolve_var_refs:
push rbp push rbp
mov rbp, rsp mov rbp, rsp
push r15
push r14 xchg rsi, rdx
push rbx mov rcx, ast_resolve_var_refs_for_each
call ast_walk_for_each
.epilogue: .epilogue:
add rsp, 8
pop rbx
pop r14
pop r15
pop rbp pop rbp
ret ret

View file

@ -44,37 +44,41 @@ fn main() {
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);
let symtable = symtable.assume_init(); let mut symtable = symtable.assume_init();
use util::DisplayedSliceExt; use util::DisplayedSliceExt;
println!( println!(
"Symbol Table: {:#?}", "Symbol Table: {:#?}",
symtable.symtable.as_slice().displayed() symtable.symtable.as_slice().displayed()
); );
util::defs::ast_resolve_var_refs(&mut ast, &mut symtable, expr_id);
println!("{:#}", &ast);
}; };
} }
print_ast(b"3 + 4", |ast| unsafe { parse_expr(ast) }); // print_ast(b"3 + 4", |ast| unsafe { parse_expr(ast) });
print_ast(b"fn main() -> void { return 1 + 2; }", |ast| unsafe { // print_ast(b"fn main() -> void { return 1 + 2; }", |ast| unsafe {
parse_func(ast) // parse_func(ast)
}); // });
print_ast(b"fn main() -> void { return (1 + (2)); }", |ast| unsafe { // print_ast(b"fn main() -> void { return (1 + (2)); }", |ast| unsafe {
parse_func(ast) // parse_func(ast)
}); // });
print_ast( // print_ast(
b"fn main() -> void { return (1 + (2 * 3)) / 4; }", // b"fn main() -> void { return (1 + (2 * 3)) / 4; }",
|ast| unsafe { parse_func(ast) }, // |ast| unsafe { parse_func(ast) },
); // );
print_ast(b"fn main() -> void { return 1 + 2 * 3; }", |ast| unsafe { // print_ast(b"fn main() -> void { return 1 + 2 * 3; }", |ast| unsafe {
parse_func(ast) // parse_func(ast)
}); // });
print_ast(b"fn main() -> void { let x: u32 = 4; }", |ast| unsafe { // print_ast(b"fn main() -> void { let x: u32 = 4; }", |ast| unsafe {
parse_func(ast) // parse_func(ast)
}); // });
print_ast( // print_ast(
b"fn main(a: u32) -> void { let x: u32 = a + 4; }", // b"fn main(a: u32) -> void { let x: u32 = a + 4; }",
|ast| unsafe { parse_func(ast) }, // |ast| unsafe { parse_func(ast) },
); // );
print_ast( print_ast(
b"fn main(a: u32) -> void { b"fn main(a: u32) -> void {
let y: u32 = a + 4; let y: u32 = a + 4;

View file

@ -16,7 +16,7 @@ unsafe extern "C" {
pub unsafe fn symkey_cmp(a: *const SymKey, b: *const SymKey) -> i32; pub unsafe fn symkey_cmp(a: *const SymKey, b: *const SymKey) -> i32;
pub unsafe fn ast_build_symtable(ast: *mut Ast, root_index: u64, symtable: *mut core::mem::MaybeUninit<SymbolTable>); pub unsafe fn ast_build_symtable(ast: *mut Ast, root_index: u64, symtable: *mut core::mem::MaybeUninit<SymbolTable>);
pub unsafe fn ast_walk_for_each(ast: *mut Ast, start_index: u64, ctx: *mut (), for_each: unsafe extern "C" fn(ctx: *mut (), *mut Ast, node_index: u64, scope: u64)); pub unsafe fn ast_walk_for_each(ast: *mut Ast, start_index: u64, ctx: *mut (), for_each: unsafe extern "C" fn(ctx: *mut (), *mut Ast, node_index: u64, scope: u64));
pub unsafe fn ast_resolve_var_refs(ast: *mut Ast); pub unsafe fn ast_resolve_var_refs(ast: *mut Ast, ctx: *mut SymbolTable, root_index: u64);
} }
pub const AST_FUNCTION: u8 = 1; pub const AST_FUNCTION: u8 = 1;