diff --git a/lang/src/ast.asm b/lang/src/ast.asm index 17ff97b..89e23fc 100644 --- a/lang/src/ast.asm +++ b/lang/src/ast.asm @@ -77,6 +77,18 @@ parse_func: push rbp mov rbp, rsp push rdi + + ; start-structs + ; struct AstFunction { + ; name: *const u8, + ; name_len: usize, + ; args: *const Argument, + ; args_len: usize, + ; return_type: Type, + ; body: u64, + ; } + ; end-structs + sub rsp, 48 ; name: *const u8 [0..8] ; name_len: usize [8..16] @@ -380,17 +392,16 @@ parse_statement: mov dil, TOKEN_RETURN call expect_token test rax, rax - jz .return + jnz .return jmp .panic .return: + mov rdi, [rsp + 24] ; Ast call parse_expr - mov [rsp + 16], rax ; expression mov byte [rsp], AST_RETURN_STATEMENT ; kind - lea rax, [rsp + 16] ; data ptr - mov [rsp + 8], rax ; data - mov rdi, [rsp + 24] ; Ast - mov rsi, rsp ; AstNode + mov [rsp + 8], rax ; data + mov rdi, [rsp + 24] ; Ast + lea rsi, [rsp] ; AstNode call vec_push mov rdi, [rsp + 24] ; Ast mov rax, [rdi + 8] ; Ast.nodes.len() @@ -411,7 +422,6 @@ parse_statement: parse_block: push rbp mov rbp, rsp - push rdi ; start-structs ; struct Block { @@ -420,31 +430,46 @@ parse_block: ; } ; end-structs - sub rsp, 56 - ; statements: Vec [0..40] - ; statement: u64 [40..48] + ; Ast: *mut Ast [56..64] + ; statements: Vec [8..56] + ; statement: u64 [0..8] + sub rsp, 64 + mov [rsp + 56], rdi ; Ast mov dil, TOKEN_LBRACE call unwrap_token -.loop: - mov rdi, [rsp + 16] ; Ast - call parse_statement + + mov dil, TOKEN_RBRACE + call peek_expect_token test rax, rax - je .done - lea rdi, [rsp + 16] ; vec - mov [rsp + 8], rax ; statement - lea rsi, [rsp + 8] + jnz .done + + lea rdi, [rsp + 8] + mov rsi, 8 ; size of statement + mov rdx, 0 ; drop = None + mov rcx, 64 ; capacity + call vec_init_with + +.loop: + mov dil, TOKEN_RBRACE + call peek_expect_token + test rax, rax + jnz .done + mov rdi, [rsp + 56] ; Ast + call parse_statement + lea rdi, [rsp + 8] ; vec + mov [rsp], rax ; statement + lea rsi, [rsp] call vec_push jmp .loop .done: mov rdi, [rsp + 56] ; Ast - lea rsi, [rsp + 16] ; statements vec-slice + lea rsi, [rsp + 8] ; statements vec-slice call vec_push mov rdi, [rsp + 56] ; Ast mov rax, [rdi + 8] ; Ast.nodes.len() dec rax - add rsp, 56 - pop rdi + add rsp, 64 pop rbp ret diff --git a/lang/src/tokeniser.asm b/lang/src/tokeniser.asm index d94e0f4..f37b87c 100644 --- a/lang/src/tokeniser.asm +++ b/lang/src/tokeniser.asm @@ -557,11 +557,13 @@ unwrap_token: .panic: call panic +;; returns 0 if token not found, else returns lexeme (ptr, len) ;; dil: expected token peek_expect_token: push rbp mov rbp, rsp - push qword [rel cursor] + mov rax, [rel cursor] + push rax call expect_token pop rdi mov [rel cursor], rdi @@ -573,7 +575,8 @@ peek_lexeme: push rbp mov rbp, rsp push rdi - push qword [rel cursor] ; save cursor + mov rax, [rel cursor] ; current cursor + push rax call find_lexeme pop rdi mov [rel cursor], rdi ; restore cursor diff --git a/lang/tests/ast.rs b/lang/tests/ast.rs index 64c2d95..2883b8e 100644 --- a/lang/tests/ast.rs +++ b/lang/tests/ast.rs @@ -7,7 +7,7 @@ unsafe extern "C" { unsafe fn tokeniser_init_buf(bytes: *const u8, len: usize) -> (); } -use util::defs::{Ast, AstNode, parse_expr, parse_func}; +use util::defs::{parse_expr, parse_func, Ast, AstNode}; fn main() { unsafe { @@ -39,7 +39,9 @@ fn main() { impl std::fmt::Display for AstNode { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - use util::defs::{AST_BINARY_OP, AST_NUMBER, BinaryExpr}; + use util::defs::{ + BinaryExpr, AST_BINARY_OP, AST_FUNCTION, AST_NUMBER, AST_RETURN_STATEMENT, + }; match self.kind as u32 { AST_NUMBER => { write!(f, "Number({})", self.data as usize) @@ -56,6 +58,22 @@ impl std::fmt::Display for AstNode { operator, left, right ) } + AST_RETURN_STATEMENT => { + let return_expr_id = self.data as usize; + write!(f, "ReturnStatement(expr: {})", return_expr_id) + } + AST_FUNCTION => { + let func = unsafe { self.data.cast::().read() }; + write!( + f, + "Function(name: {:?}, return_type: {:?}, body: {})", + unsafe { + std::str::from_utf8(std::slice::from_raw_parts(func.name, func.name_len)) + }, + func.return_type, + func.body + ) + } _ => write!(f, "UnknownNode"), } } diff --git a/lang/tests/shared/defs.rs b/lang/tests/shared/defs.rs index 0a001ef..930fbb2 100644 --- a/lang/tests/shared/defs.rs +++ b/lang/tests/shared/defs.rs @@ -86,6 +86,17 @@ pub struct Type { pub kind: u8, } +#[repr(C)] +#[derive(Debug)] +pub struct AstFunction { + pub name: *const u8, + pub name_len: usize, + pub args: *const Argument, + pub args_len: usize, + pub return_type: Type, + pub body: u64, +} + #[repr(C)] #[derive(Debug)] pub struct BinaryExpr {