build symbol table

This commit is contained in:
janis 2025-10-30 22:16:45 +01:00
parent ad3b0205c2
commit 56354237c6
Signed by: janis
SSH key fingerprint: SHA256:bB1qbbqmDXZNT0KKD5c2Dfjg53JGhj7B3CFcLIzSqq8
6 changed files with 87 additions and 33 deletions

View file

@ -1013,13 +1013,15 @@ symkey_cmp:
ret ret
section .rdata section .rdata
KEY_SCOPE equ 1 ;; start-consts
KEY_SCOPE_NAME equ 2 SYM_KEY_SCOPE equ 1 ; :u8
KEY_PARENT_SCOPE equ 3 SYM_KEY_SCOPE_NAME equ 2 ; :u8
KEY_START_LOCALS equ 4 SYM_KEY_PARENT_SCOPE equ 3 ; :u8
KEY_ARG equ 5 SYM_KEY_START_LOCALS equ 4 ; :u8
KEY_VAR equ 6 SYM_KEY_ARG equ 5 ; :u8
KEY_END_LOCALS equ 7 SYM_KEY_VAR equ 6 ; :u8
SYM_KEY_END_LOCALS equ 7 ; :u8
;; end-consts
section .text section .text
@ -1066,7 +1068,7 @@ ast_build_symtable:
mov rdx, 40 ; size_of::<Vec<SymEntry>> mov rdx, 40 ; size_of::<Vec<SymEntry>>
call memcpy call memcpy
add rsp, 96 add rsp, 104
pop rbp pop rbp
ret ret
@ -1159,11 +1161,11 @@ ast_build_symtable_for_each:
jmp .done jmp .done
.func: .func:
; insert scope entry ; insert scope entry
mov byte [rsp + 32], KEY_SCOPE ; SymKey.kind mov byte [rsp + 32], SYM_KEY_SCOPE ; SymKey.kind
mov rdx, [rsp + 16] ; index mov rdx, [rsp + 16] ; index
mov qword [rsp + 40], rdx ; SymKey.scope_index mov qword [rsp + 40], rdx ; SymKey.scope_index
mov qword [rsp + 48], 0 ; SymKey.span mov qword [rsp + 48], 0 ; SymKey.span
mov qword [rsp + 56], 0 ; SymKey.ident mov qword [rsp + 56], 1 ; SymKey.ident
mov qword [rsp + 64], 0 ; SymKey.ident_len mov qword [rsp + 64], 0 ; SymKey.ident_len
; mov rbx, [rax + 16] ; AstNode.data ; mov rbx, [rax + 16] ; AstNode.data
@ -1192,12 +1194,13 @@ ast_build_symtable_for_each:
jmp .done jmp .done
.var_decl: .var_decl:
; insert variable entry ; insert variable entry
mov byte [rsp + 32], KEY_VAR ; SymKey.kind mov byte [rsp + 32], SYM_KEY_VAR ; SymKey.kind
; TODO: set span correctly ; TODO: set span correctly
mov qword [rsp + 48], 0 ; SymKey.span mov qword [rsp + 48], 0 ; SymKey.span
mov rbx, [rsp + 24] ; AstNode.data mov rbx, [rsp + 24] ; AstNode.data
mov rbx, [rbx + 8] ; AstNode.data
mov rdx, [rbx + 0] ; AstVarDecl.name mov rdx, [rbx + 0] ; AstVarDecl.name
mov rcx, [rbx + 8] ; AstVarDecl.name_len mov rcx, [rbx + 8] ; AstVarDecl.name_len
@ -1223,15 +1226,17 @@ ast_build_symtable_for_each:
mov rcx, 0 ; cmp_ctx mov rcx, 0 ; cmp_ctx
mov rdx, symkey_cmp ; cmp mov rdx, symkey_cmp ; cmp
call vec_insert_sorted call vec_insert_sorted
jmp .done
.arg: .arg:
; insert variable entry ; insert variable entry
mov byte [rsp + 32], KEY_ARG ; SymKey.kind mov byte [rsp + 32], SYM_KEY_ARG ; SymKey.kind
; TODO: set span correctly ; TODO: set span correctly
mov qword [rsp + 48], 0 ; SymKey.span mov qword [rsp + 48], 0 ; SymKey.span
mov rbx, [rsp + 24] ; AstNode.data mov rbx, [rsp + 24] ; *AstNode
mov rbx, [rbx + 8] ; AstNode.data
mov rdx, [rbx + 0] ; AstArgument.name mov rdx, [rbx + 0] ; AstArgument.name
mov rcx, [rbx + 8] ; AstArgument.name_len mov rcx, [rbx + 8] ; AstArgument.name_len
@ -1335,6 +1340,9 @@ ast_walk_for_each:
; push child indices to stack ; push child indices to stack
mov rbx, [rax + 8] ; AstNode.data mov rbx, [rax + 8] ; AstNode.data
mov r15, [rbx + 48] ; AstFunction.body
push r15 ; push body index
mov r15, [rbx + 24] ; AstFunction.args_len mov r15, [rbx + 24] ; AstFunction.args_len
xor r14, r14 ; index xor r14, r14 ; index
.arg_loop: .arg_loop:
@ -1346,8 +1354,6 @@ ast_walk_for_each:
inc r14 inc r14
jmp .arg_loop jmp .arg_loop
.arg_loop_done: .arg_loop_done:
mov r15, [rbx + 48] ; AstFunction.body
push r15 ; push body index
jmp .loop jmp .loop
.block: .block:

View file

@ -544,8 +544,8 @@ vec_binary_search_by:
mov rax, [rdi + 8] ; len mov rax, [rdi + 8] ; len
dec rax ; high dec rax ; high
mov qword [rsp + 0x20], 0 ; low mov qword [rsp + 0x20], 0 ; low
mov [rsp + 0x28], rax ; mid mov qword [rsp + 0x28], 0 ; mid
mov [rsp + 0x30], rax ; high mov [rsp + 0x30], rax ; high
mov rax, [rdi + 24] ; item_size mov rax, [rdi + 24] ; item_size
mov [rsp + 0x38], rax ; item_size mov [rsp + 0x38], rax ; item_size

View file

@ -29,18 +29,22 @@ fn main() {
eprintln!("Parsed expression ID: {}", expr_id); eprintln!("Parsed expression ID: {}", expr_id);
println!("{:#}", &ast); println!("{:#}", &ast);
unsafe extern "C" fn visit_node(_this: *mut (), ast: *mut Ast, node_id: u64) { // unsafe extern "C" fn visit_node(_this: *mut (), ast: *mut Ast, node_id: u64) {
let ast = unsafe { &*ast }; // let ast = unsafe { &*ast };
let node = ast.nodes.get(node_id as usize).unwrap(); // let node = ast.nodes.get(node_id as usize).unwrap();
eprintln!("Visiting node {node_id}: {node}"); // eprintln!("Visiting node {node_id}: {node}");
} // }
util::defs::ast_walk_for_each(&mut ast, expr_id, core::ptr::null_mut(), visit_node); // util::defs::ast_walk_for_each(&mut ast, expr_id, core::ptr::null_mut(), visit_node);
// 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 symtable = symtable.assume_init();
// println!("Symbol Table: {:#?}", symtable); use util::DisplayedSliceExt;
println!(
"Symbol Table: {:#?}",
symtable.symtable.as_slice().displayed()
);
}; };
} }
@ -59,9 +63,9 @@ fn main() {
// 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) },
@ -203,7 +207,16 @@ impl core::fmt::Display for util::defs::SymEntry {
f.debug_struct("SymEntry") f.debug_struct("SymEntry")
.field_with("key", |f| { .field_with("key", |f| {
f.debug_struct("Key") f.debug_struct("Key")
.field("kind", &self.key.kind) .field_with("kind", |f| {
f.write_str(match self.key.kind {
util::defs::SYM_KEY_SCOPE => "Scope",
util::defs::SYM_KEY_SCOPE_NAME => "ScopeName",
util::defs::SYM_KEY_PARENT_SCOPE => "ParentScope",
util::defs::SYM_KEY_ARG => "Argument",
util::defs::SYM_KEY_VAR => "Variable",
_ => "Unknown",
})
})
.field("scope", &self.key.scope_index) .field("scope", &self.key.scope_index)
.field("span", &self.key.span) .field("span", &self.key.span)
.field_with("ident", |f| { .field_with("ident", |f| {
@ -220,7 +233,7 @@ impl core::fmt::Display for util::defs::SymEntry {
let stct = &mut f.debug_struct("Value"); let stct = &mut f.debug_struct("Value");
if self.extra == 0 { if self.extra == 0 {
stct.field("ast_index", &self.index).finish() stct.field("ast_index", &self.index).finish()
} else { } else if self.index != 0 {
stct.field_with("ident", |f| { stct.field_with("ident", |f| {
f.write_str(unsafe { f.write_str(unsafe {
core::str::from_utf8_unchecked(core::slice::from_raw_parts( core::str::from_utf8_unchecked(core::slice::from_raw_parts(
@ -230,6 +243,10 @@ impl core::fmt::Display for util::defs::SymEntry {
}) })
}) })
.finish() .finish()
} else {
stct.field("index", &self.index)
.field("extra", &self.extra)
.finish()
} }
}) })
.finish() .finish()

View file

@ -39,6 +39,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 SYM_KEY_SCOPE: u8 = 1;
pub const SYM_KEY_SCOPE_NAME: u8 = 2;
pub const SYM_KEY_PARENT_SCOPE: u8 = 3;
pub const SYM_KEY_START_LOCALS: u8 = 4;
pub const SYM_KEY_ARG: u8 = 5;
pub const SYM_KEY_VAR: u8 = 6;
pub const SYM_KEY_END_LOCALS: u8 = 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;

View file

@ -382,3 +382,23 @@ impl core::fmt::Display for defs::Type {
} }
} }
} }
#[repr(transparent)]
pub struct Displayed<T: core::fmt::Display>(pub T);
impl<T: core::fmt::Display> core::fmt::Debug for Displayed<T> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(f, "{}", self.0)
}
}
pub trait DisplayedSliceExt {
type Displayed: core::fmt::Debug;
fn displayed(self) -> Self::Displayed;
}
impl<'a, T: core::fmt::Display> DisplayedSliceExt for &'a [T] {
type Displayed = &'a [Displayed<T>];
fn displayed(self) -> Self::Displayed {
unsafe { core::mem::transmute(self) }
}
}

View file

@ -1,7 +1,7 @@
#[path = "shared/shared.rs"] #[path = "shared/shared.rs"]
mod util; mod util;
use util::{BlobVec, ffi::*, vec::Vec}; use util::{ffi::*, vec::Vec, BlobVec};
fn main() { fn main() {
static mut DROPS: usize = 1; static mut DROPS: usize = 1;
@ -104,4 +104,8 @@ fn main() {
_ = vec.insert_sorted(35, cmp); _ = vec.insert_sorted(35, cmp);
assert_eq!(vec.as_slice(), &[20, 30, 35, 40, 50]); assert_eq!(vec.as_slice(), &[20, 30, 35, 40, 50]);
let mut vec = Vec::<u32>::new_with(100);
vec.insert_sorted(50, cmp);
assert_eq!(vec.as_slice(), &[50]);
} }