diff --git a/lang/src/ast.asm b/lang/src/ast.asm index 0bd8166..cabfd7f 100644 --- a/lang/src/ast.asm +++ b/lang/src/ast.asm @@ -361,7 +361,7 @@ parse_primary_expr: jnz .var_ref jmp .panic .var_ref: - mov qword [rsp + 8], 0 ; AstVarRef.resolved + mov qword [rsp + 8], -1 ; AstVarRef.resolved mov [rsp + 16], rax ; AstVarRef.name mov [rsp + 24], rdx ; AstVarRef.name_len @@ -886,11 +886,12 @@ ast_parse_let: ; } ; end-structs - ; span: u64 [40..48] + ; expr: u64 [48..56] + ; *AstVarDecl [40..48] ; AstNode [8..40] ; AstVarDecl [8..40] ; Ast [0..8] - sub rsp, 48 + sub rsp, 56 mov [rsp], rdi ; Ast call tokeniser_get_cursor @@ -921,23 +922,9 @@ ast_parse_let: mov rdx, 32 ; size_of:: call memcpy - mov qword [rsp + 8], AST_VAR_DECL ; AstNode.kind - mov [rsp + 16], rdi ; AstNode.data - mov qword [rsp + 24], 0 ; AstNode.extra - mov rdi, [rsp + 40] ; span - mov [rsp + 32], rdi ; AstNode.span - - mov rdi, [rsp] ; Ast - lea rsi, [rsp + 8] ; &AstNode - call vec_push - ; variable is already a place - - mov rdi, [rsp] ; Ast - mov rax, [rdi + 8] ; Ast.nodes.len() - dec rax - mov qword [rsp + 8], AST_ASSIGNMENT ; AstNode.kind - mov [rsp + 16], rax ; AstNode.data (variable index) + mov [rsp + 40], rdi ; AstVarDecl ptr + ; parse the expression mov dil, TOKEN_EQUALS call unwrap_token mov rdi, [rsp] ; Ast @@ -945,10 +932,33 @@ ast_parse_let: mov rdi, [rsp] ; Ast mov rsi, rax ; expr - ; mov rdx, rdx ; is_placeness + ; mov rdx, rdx ; placeness call ast_place_to_value + mov [rsp + 48], rax ; expr index + ; variable is defined at this point so that the expression cannot reference it + call tokeniser_get_cursor + + mov rdi, [rsp + 40] ; AstVarDecl ptr + mov qword [rsp + 8], AST_VAR_DECL ; AstNode.kind + mov [rsp + 16], rdi ; AstNode.data + mov qword [rsp + 24], 0 ; AstNode.extra + mov [rsp + 32], rax ; AstNode.span + + mov rdi, [rsp] ; Ast + lea rsi, [rsp + 8] ; &AstNode + call vec_push + ; variables are places + mov rdi, [rsp] ; Ast + mov rax, [rdi + 8] ; Ast.nodes.len() + dec rax + + mov qword [rsp + 8], AST_ASSIGNMENT ; AstNode.kind + mov [rsp + 16], rax ; AstNode.data (variable index) + + mov rax, [rsp + 48] ; expr index mov [rsp + 24], rax ; AstNode.extra (expr index) + ; reuse span from variable declaration mov rdi, [rsp] ; Ast lea rsi, [rsp + 8] ; &AstNode call vec_push @@ -956,7 +966,7 @@ ast_parse_let: mov rax, [rdi + 8] ; Ast.nodes.len() dec rax - add rsp, 48 + add rsp, 56 xor rdx, rdx ; placeness = false pop rbp ret @@ -1478,16 +1488,78 @@ ast_walk_for_each: pop rbp ret -;; rdi: Ctx -;; rsi: Ast +;; rdi: BuildSymtableCtx +;; rsi: *mut Ast ;; rdx: node_index ast_resolve_var_refs_for_each: push rbp mov rbp, rsp + push rbx + + ; SymEntry [24..80] + ; *AstNode [16..24] + ; *BuildSymtableCtx [8..16] + ; *Ast [0..8] + sub rsp, 24 + mov [rsp], rsi ; Ast + mov [rsp + 8], rdi ; Ctx + + mov rdi, rsi ; Ast + mov rsi, rdx ; node_index + call vec_get + mov [rsp + 16], rax ; *AstNode + + mov bl, byte [rax] ; AstNode.kind + + cmp bl, AST_VAR_REF + jne .epilogue + + ; lookup variable in symbol table + + ; get current scope index + mov qword [rsp + 32], 0 ; SymKey.scope_index = default + mov rdi, [rsp + 8] ; *Ctx + lea rdi, [rdi + 0] ; Ctx.scope_stack + mov rsi, [rdi + 8] ; Ctx.scope_stack.len() + dec rsi + 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 + mov rdi, [rsp + 8] ; *Ctx + lea rdi, [rdi + 40] ; Ctx.symtable + lea rsi, [rsp + 24] ; &SymKey + mov rdx, 0 ; cmp_ctx + mov rcx, symkey_cmp ; cmp + call vec_binary_search_by + test rdx, rdx + jnz .panic + + mov rdx, [rsp + 16] ; *AstNode + mov rdx, [rdx + 8] ; AstNode.data + mov [rdx + 0], rax ; AstVarRef.resolved_index + .epilogue: + add rsp, 24 + pop rbx pop rbp ret +.panic: + call panic ;; rdi: Ast ;; define-fn: fn ast_resolve_var_refs(ast: *mut Ast) diff --git a/lang/tests/ast.rs b/lang/tests/ast.rs index a0af80f..ee94068 100644 --- a/lang/tests/ast.rs +++ b/lang/tests/ast.rs @@ -110,7 +110,7 @@ impl std::fmt::Display for AstNode { } AST_VAR_REF => { let var_ref = unsafe { self.data.cast::().read() }; - if var_ref.resolved != 0 { + if var_ref.resolved != u64::MAX { write!(f, "VarRef({})", var_ref.resolved) } else { write!(f, "VarRef(name: {:?})", unsafe {