diff --git a/lang/src/ast.asm b/lang/src/ast.asm index 012ceaf..ff0c50a 100644 --- a/lang/src/ast.asm +++ b/lang/src/ast.asm @@ -1356,7 +1356,7 @@ ast_build_symtable_for_each: .arg: ; insert variable entry - mov byte [rsp + 32], SYM_KEY_ARG ; SymKey.kind + mov byte [rsp + 32], SYM_KEY_VAR ; SymKey.kind mov rdx, [rax + 24] ; AstNode.span mov qword [rsp + 48], rdx ; SymKey.span @@ -1606,14 +1606,21 @@ ast_resolve_var_refs_for_each: cmp bl, AST_VAR_REF jne .epilogue +.var_ref: ; lookup variable in symbol table ; binary search lower bound mov byte [rsp + 24 + 0], SYM_KEY_START_LOCALS ; SymKey.kind - mov qword [rsp + 24 + 8], 0 ; SymKey.scope_index + mov rax, [rsp + 80] ; scope + mov [rsp + 24 + 8], rax ; SymKey.scope_index mov qword [rsp + 24 + 16], 0 ; SymKey.span - mov qword [rsp + 24 + 24], 1 ; SymKey.name - mov qword [rsp + 24 + 32], 0 ; SymKey.name_len + ; name + mov rax, [rsp + 16] ; *AstNode + 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 @@ -1630,11 +1637,6 @@ ast_resolve_var_refs_for_each: 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 @@ -1648,16 +1650,60 @@ ast_resolve_var_refs_for_each: .fixup: cmp rax, [rsp + 88] ; lower_bound - jl .panic + jl .parent mov rdi, [rsp + 8] ; *Ctx mov rsi, rax ; index call vec_get - mov rax, [rax + 40] ; SymEntry.index + mov rbx, rax ; *SymEntry + + ; compare symbol ident with var_ref ident + mov rdi, [rbx + 24] ; SymEntry.key.ident + mov rsi, [rbx + 32] ; SymEntry.key.ident_len + + mov rax, [rsp + 16] ; *AstNode + mov rax, [rax + 8] ; AstNode.data + mov rdx, [rax + 8] ; AstVarRef.name + mov rcx, [rax + 16] ; AstVarRef.name_len + call strcmp + test rax, rax + jnz .parent + + ; load SymEntry.index + mov rax, [rbx + 40] ; SymEntry.index mov rdx, [rsp + 16] ; *AstNode mov rdx, [rdx + 8] ; AstNode.data mov [rdx + 0], rax ; AstVarRef.resolved_index + jmp .epilogue + +.parent: + ; binary search for parent scope + mov byte [rsp + 24 + 0], SYM_KEY_PARENT_SCOPE ; SymKey.kind + mov rax, [rsp + 80] ; scope + mov [rsp + 24 + 8], rax ; SymKey.scope_index + mov qword [rsp + 24 + 16], 0 ; SymKey.span + mov qword [rsp + 24 + 24], 1 ; SymKey.ident + mov qword [rsp + 24 + 32], 0 ; 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 + test rdx, rdx + jnz .panic ; can't find the symbol entry for this var-ref + + ; load parent scope sym entry + mov rdi, [rsp + 8] ; *Ctx + mov rsi, rax ; index + call vec_get + mov rbx, rax ; *SymEntry + + mov rdx, [rax + 40] ; SymEntry.index (parent scope) + mov [rsp + 80], rdx ; update scope + jmp .var_ref .epilogue: add rsp, 96