Compare commits

...

8 commits

3 changed files with 393 additions and 166 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
@ -82,6 +83,7 @@ global ast_walk_for_each
;; kind: u8, ;; kind: u8,
;; data: *const (), ;; data: *const (),
;; extra: usize, ;; extra: usize,
;; span: u64,
;; } ;; }
;; ;;
;; struct AstArgument { ;; struct AstArgument {
@ -101,6 +103,7 @@ global ast_walk_for_each
parse_func: parse_func:
push rbp push rbp
mov rbp, rsp mov rbp, rsp
sub rsp, 8 ; span
push rdi push rdi
; start-structs ; start-structs
@ -114,17 +117,21 @@ parse_func:
; } ; }
; end-structs ; end-structs
sub rsp, 56 ; span: u64 [64..72]
; name: *const u8 [0..8]
; name_len: usize [8..16]
; args_ptr: *const u64 [16..24]
; args_len: usize [24..32]
; return_type: Type [32..48]
; body: u64 [48..56]
; ast: *mut Ast [56..64] ; ast: *mut Ast [56..64]
; body: u64 [48..56]
; return_type: Type [32..48]
; args_len: usize [24..32]
; args_ptr: *const u64 [16..24]
; name_len: usize [8..16]
; name: *const u8 [0..8]
sub rsp, 56
mov qword [rsp + 16], 8 ; <*u64>::dangling() mov qword [rsp + 16], 8 ; <*u64>::dangling()
mov qword [rsp + 24], 0 ; args_len mov qword [rsp + 24], 0 ; args_len
call tokeniser_get_cursor
mov [rsp + 64], rax ; span
mov dil, TOKEN_FN mov dil, TOKEN_FN
call unwrap_token call unwrap_token
mov dil, TOKEN_IDENT mov dil, TOKEN_IDENT
@ -161,9 +168,11 @@ parse_func:
mov rdx, 56 ; size_of::<AstFunction> mov rdx, 56 ; size_of::<AstFunction>
call memcpy call memcpy
mov byte [rsp], AST_FUNCTION ; kind mov byte [rsp], AST_FUNCTION ; AstNode.kind
mov [rsp + 8], rdi ; data mov [rsp + 8], rdi ; AstNode.data
mov qword [rsp + 16], 0 ; extra mov qword [rsp + 16], 0 ; AstNode.extra
mov rdi, [rsp + 64] ; span
mov [rsp + 24], rdi ; AstNode.span
mov rdi, [rsp + 56] ; Ast mov rdi, [rsp + 56] ; Ast
lea rsi, [rsp] ; &AstNode lea rsi, [rsp] ; &AstNode
call vec_push call vec_push
@ -172,6 +181,7 @@ parse_func:
dec rax dec rax
add rsp, 56 add rsp, 56
pop rdi pop rdi
add rsp, 8
pop rbp pop rbp
ret ret
@ -189,6 +199,7 @@ parse_func:
parse_args: parse_args:
push rbp push rbp
mov rbp, rsp mov rbp, rsp
; span: u64 [80..88]
; vec: [40..80] ; vec: [40..80]
; argument: AstArgument { [8..40] ; argument: AstArgument { [8..40]
; name: *const u8 [8..16] ; name: *const u8 [8..16]
@ -196,7 +207,7 @@ parse_args:
; arg_type: Type [24..40] ; arg_type: Type [24..40]
; } ; }
; ast [0..8] ; ast [0..8]
sub rsp, 80 sub rsp, 88
mov [rsp], rdi ; Ast mov [rsp], rdi ; Ast
lea rdi, [rsp + 40] ; vec lea rdi, [rsp + 40] ; vec
@ -210,6 +221,10 @@ parse_args:
call expect_token call expect_token
test rax, rax test rax, rax
jnz .done_args jnz .done_args
call tokeniser_get_cursor
mov [rsp + 80], rax ; span
mov dil, TOKEN_IDENT mov dil, TOKEN_IDENT
call unwrap_token call unwrap_token
mov [rsp + 8], rax ; AstArgument.name mov [rsp + 8], rax ; AstArgument.name
@ -232,6 +247,8 @@ parse_args:
mov qword [rsp + 8], AST_ARG ; AstNode.kind mov qword [rsp + 8], AST_ARG ; AstNode.kind
mov [rsp + 16], rdi ; AstNode.data mov [rsp + 16], rdi ; AstNode.data
mov qword [rsp + 24], 0 ; AstNode.extra mov qword [rsp + 24], 0 ; AstNode.extra
mov rdi, [rsp + 80] ; span
mov [rsp + 32], rdi ; AstNode.span
mov rdi, [rsp] ; Ast mov rdi, [rsp] ; Ast
lea rsi, [rsp + 8] ; &AstNode lea rsi, [rsp + 8] ; &AstNode
@ -256,7 +273,7 @@ parse_args:
.done_args: .done_args:
mov rax, [rsp + 40] ; args_ptr mov rax, [rsp + 40] ; args_ptr
mov rdx, [rsp + 48] ; args_len mov rdx, [rsp + 48] ; args_len
add rsp, 80 add rsp, 88
pop rbp pop rbp
ret ret
@ -317,7 +334,7 @@ parse_number:
parse_primary_expr: parse_primary_expr:
push rbp push rbp
mov rbp, rsp mov rbp, rsp
sub rsp, 32 sub rsp, 40
mov [rsp], rdi ; Ast mov [rsp], rdi ; Ast
; start-structs ; start-structs
@ -328,6 +345,9 @@ parse_primary_expr:
; } ; }
; end-structs ; end-structs
call tokeniser_get_cursor
mov [rsp + 32], rax ; span
mov dil, TOKEN_NUMBER mov dil, TOKEN_NUMBER
call expect_token call expect_token
test rax, rax test rax, rax
@ -342,7 +362,7 @@ parse_primary_expr:
jnz .var_ref jnz .var_ref
jmp .panic jmp .panic
.var_ref: .var_ref:
mov qword [rsp + 8], 0 ; AstVarRef.resolved mov qword [rsp + 8], -1 ; AstVarRef.resolved
mov [rsp + 16], rax ; AstVarRef.name mov [rsp + 16], rax ; AstVarRef.name
mov [rsp + 24], rdx ; AstVarRef.name_len mov [rsp + 24], rdx ; AstVarRef.name_len
@ -357,6 +377,7 @@ parse_primary_expr:
mov qword [rsp + 8], AST_VAR_REF ; AstNode.kind mov qword [rsp + 8], AST_VAR_REF ; AstNode.kind
mov [rsp + 16], rdi ; AstNode.data mov [rsp + 16], rdi ; AstNode.data
mov qword [rsp + 24], 0 ; AstNode.extra mov qword [rsp + 24], 0 ; AstNode.extra
; mov [rsp + 32], span ; AstNode.span
mov rdi, [rsp] ; Ast mov rdi, [rsp] ; Ast
lea rsi, [rsp + 8] ; &AstNode lea rsi, [rsp + 8] ; &AstNode
call vec_push call vec_push
@ -370,9 +391,10 @@ parse_primary_expr:
mov rsi, rdx ; lexeme len mov rsi, rdx ; lexeme len
call parse_number call parse_number
mov rdi, [rsp] ; Ast mov rdi, [rsp] ; Ast
mov byte [rsp + 8], AST_NUMBER ; kind mov byte [rsp + 8], AST_NUMBER ; AstNode.kind
mov [rsp + 16], rax ; data mov [rsp + 16], rax ; AstNode.data
mov qword [rsp + 24], 0 ; extra mov qword [rsp + 24], 0 ; AstNode.extra
; mov [rsp + 32], [rsp + 32] ; AstNode.span
lea rsi, [rsp + 8] ; &AstNode lea rsi, [rsp + 8] ; &AstNode
call vec_push call vec_push
mov rdi, [rsp] ; Ast mov rdi, [rsp] ; Ast
@ -388,7 +410,7 @@ parse_primary_expr:
call unwrap_token call unwrap_token
mov rax, [rsp + 8] ; expr mov rax, [rsp + 8] ; expr
.epilogue: .epilogue:
add rsp, 32 add rsp, 40
pop rbp pop rbp
ret ret
.panic: .panic:
@ -412,6 +434,8 @@ parse_binary_expr:
; end-structs ; end-structs
sub rsp, 64 sub rsp, 64
; span: u64 [56..64]
; AstNode [32..64]
; lexeme: Lexeme [32..56] ; lexeme: Lexeme [32..56]
; right: u64 [24..32] ; right: u64 [24..32]
; right_placeness: u8 [20..21] ; right_placeness: u8 [20..21]
@ -426,6 +450,9 @@ parse_binary_expr:
mov byte [rsp + 17], sil ; upper_precedence mov byte [rsp + 17], sil ; upper_precedence
mov byte [rsp + 16], 0 mov byte [rsp + 16], 0
call tokeniser_get_cursor
mov [rsp + 56], rax ; span
call parse_prefix_expr call parse_prefix_expr
mov [rsp + 8], rax ; left mov [rsp + 8], rax ; left
mov [rsp + 19], dl ; left_placeness mov [rsp + 19], dl ; left_placeness
@ -510,6 +537,7 @@ parse_binary_expr:
mov byte [rsp + 32], AST_BINARY_OP ; AstNode.kind mov byte [rsp + 32], AST_BINARY_OP ; AstNode.kind
mov [rsp + 40], rax ; AstNode.data mov [rsp + 40], rax ; AstNode.data
mov qword [rsp + 48], 0 ; AstNode.extra mov qword [rsp + 48], 0 ; AstNode.extra
; mov [rsp + 56], [rsp + 56] ; AstNode.span
mov rdi, [rsp] ; Ast mov rdi, [rsp] ; Ast
lea rsi, [rsp + 32] ; &AstNode lea rsi, [rsp + 32] ; &AstNode
call vec_push call vec_push
@ -547,10 +575,13 @@ parse_statement:
push rbp push rbp
mov rbp, rsp mov rbp, rsp
; Ast [24..32] ; AstNode [8..40]
; AstNode [0..24] ; Ast [0..8]
sub rsp, 32 sub rsp, 40
mov [rsp + 24], rdi ; Ast mov [rsp], rdi ; Ast
call tokeniser_get_cursor
mov [rsp + 32], rax ; AstNode.span
mov dil, TOKEN_RETURN mov dil, TOKEN_RETURN
call expect_token call expect_token
@ -563,21 +594,21 @@ parse_statement:
jmp .panic jmp .panic
.let: .let:
mov rdi, [rsp + 24] ; Ast mov rdi, [rsp] ; Ast
call ast_parse_let call ast_parse_let
mov [rsp], rax ; statement mov [rsp], rax ; statement
jmp .semi jmp .semi
.return: .return:
mov rdi, [rsp + 24] ; Ast mov rdi, [rsp] ; Ast
call parse_expr call parse_expr
mov byte [rsp], AST_RETURN_STATEMENT ; kind mov byte [rsp + 8], AST_RETURN_STATEMENT ; AstNode.kind
mov [rsp + 8], rax ; data mov [rsp + 16], rax ; AstNode.data
mov qword [rsp + 16], 0 ; extra mov qword [rsp + 24], 0 ; AstNode.extra
mov rdi, [rsp + 24] ; Ast mov rdi, [rsp] ; Ast
lea rsi, [rsp] ; &AstNode lea rsi, [rsp + 8] ; &AstNode
call vec_push call vec_push
mov rdi, [rsp + 24] ; Ast mov rdi, [rsp] ; Ast
mov rax, [rdi + 8] ; Ast.nodes.len() mov rax, [rdi + 8] ; Ast.nodes.len()
dec rax dec rax
mov [rsp], rax mov [rsp], rax
@ -586,7 +617,7 @@ parse_statement:
mov dil, TOKEN_SEMI mov dil, TOKEN_SEMI
call unwrap_token call unwrap_token
mov rax, [rsp] ; expression mov rax, [rsp] ; expression
add rsp, 32 add rsp, 40
pop rbp pop rbp
ret ret
.panic: .panic:
@ -598,12 +629,16 @@ parse_block:
push rbp push rbp
mov rbp, rsp mov rbp, rsp
; span: u64 [64..72]
; Ast: *mut Ast [56..64] ; Ast: *mut Ast [56..64]
; statements: Vec<Statement> [8..56] ; statements: Vec<Statement> [8..56]
; statement: u64 [0..8] ; statement: u64 [0..8]
sub rsp, 64 sub rsp, 72
mov [rsp + 56], rdi ; Ast mov [rsp + 56], rdi ; Ast
call tokeniser_get_cursor
mov [rsp + 64], rax ; span
mov dil, TOKEN_LBRACE mov dil, TOKEN_LBRACE
call unwrap_token call unwrap_token
@ -632,13 +667,15 @@ parse_block:
jmp .loop jmp .loop
.done: .done:
mov rdi, [rsp + 56] ; Ast mov rdi, [rsp + 56] ; Ast
mov qword [rsp], AST_BLOCK ; kind mov qword [rsp], AST_BLOCK ; AstNode.kind
mov rsi, [rsp + 64] ; span
mov [rsp + 24], rsi ; AstNode.span
lea rsi, [rsp] ; &AstNode lea rsi, [rsp] ; &AstNode
call vec_push call vec_push
mov rdi, [rsp + 56] ; Ast mov rdi, [rsp + 56] ; Ast
mov rax, [rdi + 8] ; Ast.nodes.len() mov rax, [rdi + 8] ; Ast.nodes.len()
dec rax dec rax
add rsp, 64 add rsp, 72
pop rbp pop rbp
ret ret
@ -707,11 +744,14 @@ parse_prefix_expr:
push rbp push rbp
mov rbp, rsp mov rbp, rsp
; AstNode [8..40]
; ast [0..8] ; ast [0..8]
sub rsp, 32 sub rsp, 40
mov [rsp], rdi ; Ast mov [rsp], rdi ; Ast
call tokeniser_get_cursor
mov [rsp + 32], rax ; AstNode.span
mov dil, TOKEN_STAR mov dil, TOKEN_STAR
call expect_token call expect_token
test rax, rax test rax, rax
@ -763,7 +803,7 @@ parse_prefix_expr:
jmp .done jmp .done
.done: .done:
add rsp, 32 add rsp, 40
pop rbp pop rbp
ret ret
@ -773,13 +813,17 @@ parse_assignment_expr:
push rbp push rbp
mov rbp, rsp mov rbp, rsp
; span: u64 [32..40]
; source [24..32] ; source [24..32]
; dest [16..24] ; dest [16..24]
; dest_placeness [8..9] ; dest_placeness [8..9]
; ast [0..8] ; ast [0..8]
sub rsp, 32 sub rsp, 40
mov [rsp], rdi ; Ast mov [rsp], rdi ; Ast
call tokeniser_get_cursor
mov [rsp + 32], rax ; span
mov rdi, [rsp] ; Ast mov rdi, [rsp] ; Ast
call parse_binary_expr call parse_binary_expr
mov [rsp + 16], rax ; dest mov [rsp + 16], rax ; dest
@ -796,7 +840,7 @@ parse_assignment_expr:
mov rsi, [rsp + 16] ; dest mov rsi, [rsp + 16] ; dest
movzx rdx, byte [rsp + 8] ; placeness movzx rdx, byte [rsp + 8] ; placeness
call ast_value_to_place call ast_value_to_place
mov [rsp + 16], rax ; source mov [rsp + 16], rax ; dest
mov rdi, [rsp] ; Ast mov rdi, [rsp] ; Ast
call parse_expr call parse_expr
@ -820,7 +864,7 @@ parse_assignment_expr:
.done: .done:
mov rax, [rsp + 16] ; dest mov rax, [rsp + 16] ; dest
movzx rdx, byte [rsp + 8] ; placeness movzx rdx, byte [rsp + 8] ; placeness
add rsp, 32 add rsp, 40
pop rbp pop rbp
ret ret
@ -843,12 +887,17 @@ ast_parse_let:
; } ; }
; end-structs ; end-structs
; AstNode [8..32] ; expr: u64 [48..56]
; *AstVarDecl [40..48]
; AstNode [8..40]
; AstVarDecl [8..40] ; AstVarDecl [8..40]
; Ast [0..8] ; Ast [0..8]
sub rsp, 48 sub rsp, 56
mov [rsp], rdi ; Ast mov [rsp], rdi ; Ast
call tokeniser_get_cursor
mov [rsp + 40], rax ; span
; skipped in parse_statement ; skipped in parse_statement
; mov dil, TOKEN_LET ; mov dil, TOKEN_LET
; call unwrap_token ; call unwrap_token
@ -874,21 +923,9 @@ ast_parse_let:
mov rdx, 32 ; size_of::<AstVarDecl> mov rdx, 32 ; size_of::<AstVarDecl>
call memcpy call memcpy
mov qword [rsp + 8], AST_VAR_DECL ; AstNode.kind mov [rsp + 40], rdi ; AstVarDecl ptr
mov [rsp + 16], rdi ; AstNode.data
mov qword [rsp + 24], 0 ; AstNode.extra
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)
; parse the expression
mov dil, TOKEN_EQUALS mov dil, TOKEN_EQUALS
call unwrap_token call unwrap_token
mov rdi, [rsp] ; Ast mov rdi, [rsp] ; Ast
@ -896,10 +933,33 @@ ast_parse_let:
mov rdi, [rsp] ; Ast mov rdi, [rsp] ; Ast
mov rsi, rax ; expr mov rsi, rax ; expr
; mov rdx, rdx ; is_placeness ; mov rdx, rdx ; placeness
call ast_place_to_value 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) mov [rsp + 24], rax ; AstNode.extra (expr index)
; reuse span from variable declaration
mov rdi, [rsp] ; Ast mov rdi, [rsp] ; Ast
lea rsi, [rsp + 8] ; &AstNode lea rsi, [rsp + 8] ; &AstNode
call vec_push call vec_push
@ -907,7 +967,7 @@ ast_parse_let:
mov rax, [rdi + 8] ; Ast.nodes.len() mov rax, [rdi + 8] ; Ast.nodes.len()
dec rax dec rax
add rsp, 48 add rsp, 56
xor rdx, rdx ; placeness = false xor rdx, rdx ; placeness = false
pop rbp pop rbp
ret ret
@ -924,17 +984,26 @@ ast_value_to_place:
mov rax, rsi mov rax, rsi
je .done je .done
; create new AST node ; create new AST node
sub rsp, 32 sub rsp, 40
mov [rsp], rdi mov [rsp], rdi ; Ast
mov byte [rsp + 8], AST_VALUE_TO_PLACE ; kind mov [rsp + 8], rsi ; node_index
mov [rsp + 16], rsi ; data
mov qword [rsp + 24], 0 ; extra ; load original node's span
call vec_get
mov rdi, [rax + 24] ; AstNode.span
mov [rsp + 32], rdi ; AstNode.span
mov rsi, [rsp + 8] ; node_index
mov byte [rsp + 8], AST_VALUE_TO_PLACE ; AstNode.kind
mov [rsp + 16], rsi ; AstNode.data
mov qword [rsp + 24], 0 ; AstNode.extra
lea rsi, [rsp + 8] ; &AstNode lea rsi, [rsp + 8] ; &AstNode
mov rdi, [rsp] ; Ast
call vec_push call vec_push
mov rdi, [rsp] ; Ast mov rdi, [rsp] ; Ast
mov rax, [rdi + 8] ; Ast.nodes.len() mov rax, [rdi + 8] ; Ast.nodes.len()
dec rax dec rax
add rsp, 32 add rsp, 40
.done: .done:
pop rbp pop rbp
ret ret
@ -951,17 +1020,26 @@ ast_place_to_value:
mov rax, rsi mov rax, rsi
je .done je .done
; create new AST node ; create new AST node
sub rsp, 32 sub rsp, 40
mov [rsp], rdi mov [rsp], rdi ; Ast
mov byte [rsp + 8], AST_PLACE_TO_VALUE ; kind mov [rsp + 8], rsi ; node_index
mov [rsp + 16], rsi ; data
mov qword [rsp + 24], 0 ; extra ; load original node's span
call vec_get
mov rdi, [rax + 24] ; AstNode.span
mov [rsp + 32], rdi ; AstNode.span
mov rsi, [rsp + 8] ; node_index
mov byte [rsp + 8], AST_PLACE_TO_VALUE ; AstNode.kind
mov [rsp + 16], rsi ; AstNode.data
mov qword [rsp + 24], 0 ; AstNode.extra
lea rsi, [rsp + 8] ; &AstNode lea rsi, [rsp + 8] ; &AstNode
mov rdi, [rsp] ; Ast
call vec_push call vec_push
mov rdi, [rsp] ; Ast mov rdi, [rsp] ; Ast
mov rax, [rdi + 8] ; Ast.nodes.len() mov rax, [rdi + 8] ; Ast.nodes.len()
dec rax dec rax
add rsp, 32 add rsp, 40
.done: .done:
pop rbp pop rbp
ret ret
@ -976,21 +1054,21 @@ symkey_cmp:
mov rbp, rsp mov rbp, rsp
push rbx push rbx
sub rsp, 16
mov [rsp], rsi
mov [rsp + 8], rdx
mov al, byte [rsi] ; a.kind mov al, byte [rsi] ; a.kind
mov bl, byte [rdx] ; b.kind mov bl, byte [rdx] ; b.kind
cmp al, bl cmp al, bl
jl .a_less jl .a_less
jg .a_greater jg .a_greater
mov rax, [rsi + 8] ; a.scope_index mov rax, [rsi + 8] ; a.scope_index
mov rbx, [rdx + 8] ; b.scope_index mov rbx, [rdx + 8] ; b.scope_index
cmp rax, rbx cmp rax, rbx
jl .a_less jl .a_less
jg .a_greater jg .a_greater
mov rax, [rsi + 16] ; a.span
mov rbx, [rdx + 16] ; b.span
cmp rax, rbx
jl .a_less
jg .a_greater
mov rdi, [rsi + 24] ; a.ident mov rdi, [rsi + 24] ; a.ident
mov rsi, [rsi + 32] ; a.ident_len mov rsi, [rsi + 32] ; a.ident_len
@ -1000,6 +1078,15 @@ symkey_cmp:
cmp rax, 0 cmp rax, 0
jl .a_less jl .a_less
jg .a_greater jg .a_greater
mov rsi, [rsp]
mov rdx, [rsp + 8]
mov rax, [rsi + 16] ; a.span
mov rbx, [rdx + 16] ; b.span
cmp rax, rbx
jl .a_less
jg .a_greater
xor rax, rax xor rax, rax
jmp .epilogue jmp .epilogue
.a_less: .a_less:
@ -1008,6 +1095,7 @@ symkey_cmp:
.a_greater: .a_greater:
mov rax, 1 mov rax, 1
.epilogue: .epilogue:
add rsp, 16
pop rbx pop rbx
pop rbp pop rbp
ret ret
@ -1033,23 +1121,17 @@ ast_build_symtable:
push rbp push rbp
mov rbp, rsp mov rbp, rsp
; BuildSymtableCtx [24..104] ; BuildSymtableCtx [24..64]
; *SymbolTable [16..24] ; *SymbolTable [16..24]
; root_index [8..16] ; root_index [8..16]
; Ast [0..8] ; Ast [0..8]
sub rsp, 104 sub rsp, 64
mov [rsp], rdi ; Ast mov [rsp], rdi ; Ast
mov [rsp + 8], rsi ; root_index mov [rsp + 8], rsi ; root_index
mov [rsp + 16], rdx ; *SymbolTable mov [rsp + 16], rdx ; *SymbolTable
; initialise scope_stack and symtable vecs ; initialise scope_stack and symtable vecs
lea rdi, [rsp + 24] ; &BuildSymtableCtx.scope_stack lea rdi, [rsp + 24] ; &BuildSymtableCtx.symtable
mov rsi, 8 ; size of u64
mov rdx, 0 ; drop = None
mov rcx, 128 ; capacity
call vec_init_with
lea rdi, [rsp + 24 + 40] ; &BuildSymtableCtx.symtable
mov rsi, 56 ; size_of::<SymEntry> mov rsi, 56 ; size_of::<SymEntry>
mov rdx, 0 ; drop = None mov rdx, 0 ; drop = None
mov rcx, 128 ; capacity mov rcx, 128 ; capacity
@ -1064,11 +1146,11 @@ ast_build_symtable:
; memcpy symtable out ; memcpy symtable out
mov rdi, [rsp + 16] ; *SymbolTable mov rdi, [rsp + 16] ; *SymbolTable
lea rsi, [rsp + 24 + 40] ; &BuildSymtableCtx.symtable lea rsi, [rsp + 24] ; &BuildSymtableCtx.symtable
mov rdx, 40 ; size_of::<Vec<SymEntry>> mov rdx, 40 ; size_of::<Vec<SymEntry>>
call memcpy call memcpy
add rsp, 104 add rsp, 64
pop rbp pop rbp
ret ret
@ -1118,7 +1200,6 @@ ast_build_symtable:
;; ;;
;; #start-structs ;; #start-structs
;; struct BuildSymtableCtx { ;; struct BuildSymtableCtx {
;; scope_stack: Vec<u64>,
;; symtable: Vec<SymEntry>, ;; symtable: Vec<SymEntry>,
;; } ;; }
;; #end-structs ;; #end-structs
@ -1129,21 +1210,24 @@ ast_build_symtable:
;; rdi: Ctx ;; rdi: Ctx
;; rsi: Ast ;; rsi: Ast
;; rdx: index ;; rdx: index
;; rcx: scope
ast_build_symtable_for_each: ast_build_symtable_for_each:
push rbp push rbp
mov rbp, rsp mov rbp, rsp
push rbx push rbx
; scope: u64 [88..96]
; SymEntry [32..88] ; SymEntry [32..88]
; SymKey [32..72] ; SymKey [32..72]
; *AstNode [24..32] ; *AstNode [24..32]
; index [16..24] ; index [16..24]
; ctx [8..16] ; ctx [8..16]
; ast [0..8] ; ast [0..8]
sub rsp, 88 sub rsp, 96
mov [rsp], rsi ; Ast mov [rsp], rsi ; Ast
mov [rsp + 8], rdi ; Ctx mov [rsp + 8], rdi ; Ctx
mov [rsp + 16], rdx ; index mov [rsp + 16], rdx ; index
mov [rsp + 88], rcx ; scope
mov rdi, rsi ; Ast mov rdi, rsi ; Ast
mov rsi, rdx ; index mov rsi, rdx ; index
@ -1164,40 +1248,49 @@ ast_build_symtable_for_each:
mov byte [rsp + 32], SYM_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 rdx, [rax + 24] ; AstNode.span
mov qword [rsp + 48], rdx ; SymKey.span
mov qword [rsp + 56], 1 ; 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 rdx, [rbx + 8] ; Func.name
; mov rcx, [rbx + 16] ; Func.name_len
mov rbx, [rax + 8] ; AstNode.data mov rbx, [rax + 8] ; AstNode.data
mov rdx, [rbx + 0] ; Func.name mov rdx, [rbx + 0] ; Func.name
mov rcx, [rbx + 8] ; Func.name_len mov rcx, [rbx + 8] ; Func.name_len
mov qword [rsp + 72], rdx ; SymEntry.index mov [rsp + 72], rdx ; SymEntry.index
mov qword [rsp + 80], rcx ; SymEntry.extra mov [rsp + 80], rcx ; SymEntry.extra
mov rdi, [rsp + 8] ; *Ctx mov rdi, [rsp + 8] ; Ctx.symtable
lea rdi, [rdi + 40] ; Ctx.symtable
lea rsi, [rsp + 32] ; &SymEntry lea rsi, [rsp + 32] ; &SymEntry
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
; push scope index onto scope_stack ; add parent scope
mov byte [rsp + 32], SYM_KEY_PARENT_SCOPE ; SymKey.kind
mov rdx, [rsp + 16] ; index
mov qword [rsp + 40], rdx ; SymKey.scope_index
mov qword [rsp + 48], 0 ; SymKey.span
mov qword [rsp + 56], 1 ; SymKey.ident
mov qword [rsp + 64], 0 ; SymKey.ident_len
mov rdx, [rsp + 88] ; parent scope
mov [rsp + 72], rdx ; SymEntry.index
mov qword [rsp + 80], 0 ; SymEntry.extra
mov rdi, [rsp + 8] ; *Ctx mov rdi, [rsp + 8] ; *Ctx
lea rdi, [rdi + 0] ; Ctx.scope_stack lea rsi, [rsp + 32] ; &SymEntry
lea rsi, [rsp + 16] ; &index mov rcx, 0 ; cmp_ctx
call vec_push mov rdx, symkey_cmp ; cmp
call vec_insert_sorted
jmp .done jmp .done
.var_decl: .var_decl:
; insert variable entry ; insert variable entry
mov byte [rsp + 32], SYM_KEY_VAR ; SymKey.kind mov byte [rsp + 32], SYM_KEY_VAR ; SymKey.kind
; TODO: set span correctly mov rdx, [rax + 24] ; AstNode.span
mov qword [rsp + 48], 0 ; SymKey.span mov qword [rsp + 48], rdx ; SymKey.span
mov rbx, [rsp + 24] ; AstNode.data mov rbx, [rsp + 24] ; AstNode.data
mov rbx, [rbx + 8] ; AstNode.data mov rbx, [rbx + 8] ; AstNode.data
@ -1211,17 +1304,10 @@ ast_build_symtable_for_each:
mov [rsp + 72], rdx ; SymEntry.index mov [rsp + 72], rdx ; SymEntry.index
mov qword [rsp + 80], 0 ; SymEntry.extra mov qword [rsp + 80], 0 ; SymEntry.extra
mov qword [rsp + 40], 0 ; SymKey.scope_index = default mov rdx, [rsp + 88] ; current scope
lea rdx, [rsp + 40] mov [rsp + 40], rdx ; SymKey.scope_index = default
mov rdi, [rsp + 8] ; *Ctx
mov rsi, [rdi + 8] ; Ctx.scope_stack.len()
dec rsi
call vec_get_or
mov rax, [rax] ; current scope index
mov [rsp + 40], rax ; SymKey.scope_index = scope_stack.last_or(0)
mov rdi, [rsp + 8] ; *Ctx mov rdi, [rsp + 8] ; *Ctx
lea rdi, [rdi + 40] ; Ctx.symtable
lea rsi, [rsp + 32] ; &SymEntry lea rsi, [rsp + 32] ; &SymEntry
mov rcx, 0 ; cmp_ctx mov rcx, 0 ; cmp_ctx
mov rdx, symkey_cmp ; cmp mov rdx, symkey_cmp ; cmp
@ -1232,8 +1318,8 @@ ast_build_symtable_for_each:
; insert variable entry ; insert variable entry
mov byte [rsp + 32], SYM_KEY_ARG ; SymKey.kind mov byte [rsp + 32], SYM_KEY_ARG ; SymKey.kind
; TODO: set span correctly mov rdx, [rax + 24] ; AstNode.span
mov qword [rsp + 48], 0 ; SymKey.span mov qword [rsp + 48], rdx ; SymKey.span
mov rbx, [rsp + 24] ; *AstNode mov rbx, [rsp + 24] ; *AstNode
mov rbx, [rbx + 8] ; AstNode.data mov rbx, [rbx + 8] ; AstNode.data
@ -1247,24 +1333,18 @@ ast_build_symtable_for_each:
mov [rsp + 72], rdx ; SymEntry.index mov [rsp + 72], rdx ; SymEntry.index
mov qword [rsp + 80], 0 ; SymEntry.extra mov qword [rsp + 80], 0 ; SymEntry.extra
mov qword [rsp + 40], 0 ; SymKey.scope_index = default mov rdx, [rsp + 88] ; current scope
lea rdx, [rsp + 40] mov [rsp + 40], rdx ; SymKey.scope_index = default
mov rdi, [rsp + 8] ; *Ctx
mov rsi, [rdi + 8] ; Ctx.scope_stack.len()
dec rsi
call vec_get_or
mov rax, [rax] ; current scope index
mov [rsp + 40], rax ; SymKey.scope_index = scope_stack.last_or(0)
mov rdi, [rsp + 8] ; *Ctx mov rdi, [rsp + 8] ; *Ctx
lea rdi, [rdi + 40] ; Ctx.symtable
lea rsi, [rsp + 32] ; &SymEntry lea rsi, [rsp + 32] ; &SymEntry
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
.done: .done:
add rsp, 88 add rsp, 96
pop rbx pop rbx
pop rbp pop rbp
ret ret
@ -1273,26 +1353,39 @@ ast_build_symtable_for_each:
;; rsi: start_index ;; rsi: start_index
;; rdx: ctx ;; rdx: ctx
;; rcx: for_each ;; rcx: for_each
;; define-fn: 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)) ;; define-fn: 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))
ast_walk_for_each: ast_walk_for_each:
push rbp push rbp
push r15 push r15
push r14 push r14
push rbx push rbx
; current_index [24..32] ; INVALID_SCOPE [48..56]
; current_index [40..48]
; *current_scope [32..40]
; current_node_ptr [24..32]
; for_each [16..24] ; for_each [16..24]
; ctx [8..16] ; ctx [8..16]
; ast [0..8] ; ast [0..8]
sub rsp, 32 sub rsp, 56
mov [rsp], rdi ; Ast mov [rsp], rdi ; Ast
mov [rsp + 8], rdx ; ctx mov [rsp + 8], rdx ; ctx
mov [rsp + 16], rcx ; for_each mov [rsp + 16], rcx ; for_each
mov [rsp + 24], rsi ; current_node_ptr mov qword [rsp + 24], 0 ; current_node_ptr
lea rdi, [rsp + 48] ; &INVALID_SCOPE
mov [rsp + 32], rdi ; current_scope
mov [rsp + 40], rsi ; current_index
mov qword [rsp + 48], -1 ; INVALID_SCOPE
mov rbp, rsp mov rbp, rsp
push rsi push rsi
; `current_scope` points to the index of the current scope on the stack.
; When we enter a new scope, we push `current_scope` onto the stack, then
; update it to point to the new scope index.
; When `rsp` is equal to `current_scope`, we need to additionally pop into
; `current_scope` after popping the current index.
.loop: .loop:
cmp rsp, rbp cmp rsp, rbp
jge .done jge .done
@ -1300,6 +1393,8 @@ ast_walk_for_each:
mov rdi, [rbp + 8] ; ctx mov rdi, [rbp + 8] ; ctx
mov rsi, [rbp] ; Ast mov rsi, [rbp] ; Ast
mov rdx, [rsp] ; current_index mov rdx, [rsp] ; current_index
mov rcx, [rbp + 32] ; current_scope
mov rcx, [rcx] ; current_scope value
mov rax, [rbp + 16] ; for_each mov rax, [rbp + 16] ; for_each
; align stack to 16 bytes before call ; align stack to 16 bytes before call
@ -1313,6 +1408,8 @@ ast_walk_for_each:
; get current_node_ptr ; get current_node_ptr
mov rdi, [rbp] ; Ast mov rdi, [rbp] ; Ast
pop rsi ; current_index pop rsi ; current_index
mov [rbp + 40], rsi ; update current_index
call vec_get call vec_get
mov [rbp + 24], rax ; current_node_ptr mov [rbp + 24], rax ; current_node_ptr
mov bl, byte [rax] ; AstNode.kind mov bl, byte [rax] ; AstNode.kind
@ -1334,9 +1431,14 @@ ast_walk_for_each:
je .address_of je .address_of
cmp bl, AST_RETURN_STATEMENT cmp bl, AST_RETURN_STATEMENT
je .return_statement je .return_statement
jmp .loop jmp .check_scope
.func: .func:
; push scope
push qword [rbp + 32] ; scope-ptr
push qword [rbp + 40] ; current_index
mov [rbp + 32], rsp ; update current_scope
; push child indices to stack ; push child indices to stack
mov rbx, [rax + 8] ; AstNode.data mov rbx, [rax + 8] ; AstNode.data
@ -1354,7 +1456,7 @@ ast_walk_for_each:
inc r14 inc r14
jmp .arg_loop jmp .arg_loop
.arg_loop_done: .arg_loop_done:
jmp .loop jmp .check_scope
.block: .block:
mov rbx, [rax + 8] ; AstNode.data mov rbx, [rax + 8] ; AstNode.data
@ -1368,7 +1470,7 @@ ast_walk_for_each:
push rdx ; push statement index push rdx ; push statement index
jmp .stmt_loop jmp .stmt_loop
.stmt_loop_done: .stmt_loop_done:
jmp .loop jmp .check_scope
.binary_op: .binary_op:
mov rbx, [rax + 8] ; AstNode.data mov rbx, [rax + 8] ; AstNode.data
@ -1376,14 +1478,14 @@ ast_walk_for_each:
push rdx ; push right index push rdx ; push right index
mov rdx, [rbx + 0] ; left index mov rdx, [rbx + 0] ; left index
push rdx ; push left index push rdx ; push left index
jmp .loop jmp .check_scope
.assignment: .assignment:
mov rbx, [rax + 8] ; AstNode.data = dest mov rbx, [rax + 8] ; AstNode.data = dest
mov rdx, [rax + 16] ; AstNode.extra = source mov rdx, [rax + 16] ; AstNode.extra = source
push rdx ; push source index push rdx ; push source index
push rbx ; push dest index push rbx ; push dest index
jmp .loop jmp .check_scope
.value_to_place: .value_to_place:
.place_to_value: .place_to_value:
@ -1392,30 +1494,145 @@ ast_walk_for_each:
.return_statement: .return_statement:
mov rbx, [rax + 8] ; AstNode.data mov rbx, [rax + 8] ; AstNode.data
push rbx ; push inner expr index push rbx ; push inner expr index
jmp .check_scope
.check_scope:
cmp rsp, [rbp + 32] ; current_scope
je .pop_scope
jmp .loop jmp .loop
; weird alloca thing .pop_scope:
; pop current_scope
; the stack may look something like this:
; current_scope---+
; == stack == ^ | points here
; scope-ptr[0]-+ |
; scope: func0 <-----+
; stmt0 | |
; stmt1 | |
; scope-ptr[1] ------+
; scope: block0 <-+
; stmt2
; stmt3
; ...
pop rax ; scope
pop rax ; scope_ptr
mov [rbp + 32], rax ; update current_scope pointer
jmp .check_scope
.done: .done:
add rsp, 32 add rsp, 56
pop rbx pop rbx
pop r14 pop r14
pop r15 pop r15
pop rbp pop rbp
ret ret
;; rdi: *mut SymbolTable
;; rsi: *mut Ast
;; rdx: node_index
;; rcx: scope
ast_resolve_var_refs_for_each:
push rbp
mov rbp, rsp
push rbx
; lower_bound [88..96]
; scope: u64 [80..88]
; SymEntry [24..80]
; *AstNode [16..24]
; *BuildSymtableCtx [8..16]
; *Ast [0..8]
sub rsp, 96
mov [rsp], rsi ; Ast
mov [rsp + 8], rdi ; Ctx
mov [rsp + 80], rcx ; SymKey.scope_index
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
; 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 qword [rsp + 24 + 16], 0 ; SymKey.span
mov qword [rsp + 24 + 24], 1 ; SymKey.name
mov qword [rsp + 24 + 32], 0 ; SymKey.name_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
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
test rdx, rdx
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, [rdx + 8] ; AstNode.data
mov [rdx + 0], rax ; AstVarRef.resolved_index
.epilogue:
add rsp, 96
pop rbx
pop rbp
ret
.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

@ -29,22 +29,31 @@ 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,
// scope: 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!("{scope}: 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 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);
}; };
} }
@ -66,14 +75,14 @@ fn main() {
// 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 x: u32 = a + 4; let y: u32 = a + 4;
let y: *u32 = &x; let y: *u32 = &y;
return *y; return *y;
}", }",
|ast| unsafe { parse_func(ast) }, |ast| unsafe { parse_func(ast) },
@ -110,7 +119,7 @@ impl std::fmt::Display for AstNode {
} }
AST_VAR_REF => { AST_VAR_REF => {
let var_ref = unsafe { self.data.cast::<util::defs::AstVarRef>().read() }; let var_ref = unsafe { self.data.cast::<util::defs::AstVarRef>().read() };
if var_ref.resolved != 0 { if var_ref.resolved != u64::MAX {
write!(f, "VarRef({})", var_ref.resolved) write!(f, "VarRef({})", var_ref.resolved)
} else { } else {
write!(f, "VarRef(name: {:?})", unsafe { write!(f, "VarRef(name: {:?})", unsafe {
@ -184,7 +193,7 @@ impl std::fmt::Display for AstNode {
AST_VALUE_TO_PLACE => { AST_VALUE_TO_PLACE => {
write!(f, "ValueToPlace(value: {})", self.data as usize) write!(f, "ValueToPlace(value: {})", self.data as usize)
} }
_ => write!(f, "UnknownNode"), kind => write!(f, "UnknownNode(kind: {kind})"),
} }
} }
} }

View file

@ -15,8 +15,8 @@ unsafe extern "C" {
pub unsafe fn ast_parse_let(ast: *mut Ast) -> (u64, bool); pub unsafe fn ast_parse_let(ast: *mut Ast) -> (u64, bool);
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)); 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;
@ -106,6 +106,7 @@ pub struct AstNode {
pub kind: u8, pub kind: u8,
pub data: *const (), pub data: *const (),
pub extra: usize, pub extra: usize,
pub span: u64,
} }
#[repr(C)] #[repr(C)]