From 9abd3f0f698ade682e22ad15633ceea0b2d4819f Mon Sep 17 00:00:00 2001 From: janis Date: Mon, 3 Nov 2025 21:24:02 +0100 Subject: [PATCH] parsing function call --- lang/src/ast.asm | 118 ++++++++++++++++++++++++++++++- lang/tests/ast.rs | 122 ++++++++++++++++++--------------- lang/tests/shared/ast_debug.rs | 10 ++- lang/tests/shared/defs.rs | 9 +++ 4 files changed, 197 insertions(+), 62 deletions(-) diff --git a/lang/src/ast.asm b/lang/src/ast.asm index 6a33a14..4c53dad 100644 --- a/lang/src/ast.asm +++ b/lang/src/ast.asm @@ -48,6 +48,7 @@ global parse_expr global parse_binary_expr global parse_primary_expr global parse_if_expr +global parse_postfix_expr global parse_statement global parse_block global ast_build_symtable @@ -314,6 +315,117 @@ parse_number: .panic: call panic +;; rdi: *mut Ast +;; define-fn: fn parse_postfix_expr(ast: *mut Ast) -> (u64, bool) +parse_postfix_expr: + push rbp + mov rbp, rsp + push rbx + + ; scratch [64..80] + ; params: Vec [24..64] + ; expr [16..24] + ; span: u64 [8..16] + ; ast [0..8] + sub rsp, 80 + mov [rsp], rdi ; Ast + + call parse_primary_expr + mov [rsp + 16], rax ; expr + mov [rsp + 24], rdx ; placeness + + call tokeniser_get_cursor + mov [rsp + 8], rax ; span + + mov dil, TOKEN_LPARENS + call expect_token + test rax, rax + jnz .call_expr + mov rax, [rsp + 16] ; expr + mov rdx, [rsp + 24] ; placeness + jmp .epilogue + +.call_expr: + ; start-structs + ; struct AstCallExpr { + ; callee: u64, + ; params: *const u64, + ; params_len: usize, + ; } + ; end-structs + + ; scratch [64..80] + ; params: Vec [24..64] + + mov rdi, [rsp] ; Ast + mov rsi, [rsp + 16] ; callee + mov rdx, [rsp + 24] ; placeness + call ast_place_to_value + mov [rsp + 16], rax ; callee + + lea rdi, [rsp + 24] ; params + mov rsi, 8 ; size of u64 + mov rdx, 0 ; drop = None + mov rcx, 16 ; capacity + call vec_init_with + +.params_loop: + mov dil, TOKEN_RPARENS + call expect_token + test rax, rax + jnz .params_done + + mov rdi, [rsp] ; Ast + call parse_expr + + mov rdi, [rsp] ; Ast + mov rsi, rax ; expr + call ast_place_to_value + mov [rsp + 64], rax ; value + lea rdi, [rsp + 24] ; params + lea rsi, [rsp + 64] ; &value + call vec_push + + mov dil, TOKEN_COMMA + call expect_token + test rax, rax + jz .close_parens + jmp .params_loop + +.close_parens: + mov dil, TOKEN_RPARENS + call unwrap_token +.params_done: + + mov rdi, 24 ; size_of:: + mov rsi, 8 ; align_of:: + call bump_alloc + + mov rdi, rax ; dst + lea rsi, [rsp + 16] ; &callee + mov rdx, 24 ; size_of:: + call memcpy + + mov [rsp + 16], rdi ; AstNode.data = *AstCallExpr + mov qword [rsp + 24], 0 ; AstNode.extra = 0 + mov rax, [rsp + 8] ; span + mov [rsp + 32], rax ; AstNode.span + mov qword [rsp + 8], AST_CALL ; AstNode.kind + + mov rdi, [rsp] ; Ast + lea rsi, [rsp + 8] ; &AstNode + call vec_push + mov rdi, [rsp] ; Ast + mov rax, [rdi + 8] ; return Ast.nodes.len() + dec rax + mov rdx, 0 ; placeness = false + +.epilogue: + add rsp, 80 + pop rbx + pop rbp + ret + ;; rdi: *mut Ast ;; define-fn: fn parse_primary_expr(ast: *mut Ast) -> (u64, bool) parse_primary_expr: @@ -463,11 +575,11 @@ parse_binary_expr: cmove bx, word [rel PRECEDENCE_EQ] cmp al, TOKEN_LT cmove bx, word [rel PRECEDENCE_CMP] - cmp al, TOKEN_LTEQ + cmp al, TOKEN_LEQ cmove bx, word [rel PRECEDENCE_CMP] cmp al, TOKEN_GT cmove bx, word [rel PRECEDENCE_CMP] - cmp al, TOKEN_GTEQ + cmp al, TOKEN_GEQ cmove bx, word [rel PRECEDENCE_CMP] cmp bx, -1 je .done @@ -782,7 +894,7 @@ parse_prefix_expr: jnz .address_of mov rdi, [rsp] ; Ast - call parse_primary_expr + call parse_postfix_expr jmp .done .dereference: mov rdi, [rsp] ; Ast diff --git a/lang/tests/ast.rs b/lang/tests/ast.rs index 31705a4..a708ee3 100644 --- a/lang/tests/ast.rs +++ b/lang/tests/ast.rs @@ -58,67 +58,75 @@ fn main() { }; } - print_ast( - b"fn main() -> void { return 1 * 2 + 3 * 4; }", - |ast| unsafe { parse_func(ast) }, - ); + // print_ast( + // b"fn main() -> void { return 1 * 2 + 3 * 4; }", + // |ast| unsafe { parse_func(ast) }, + // ); - print_ast(b"3 + 4", |ast| unsafe { parse_expr(ast) }); - print_ast(b"fn main() -> void { return 1 + 2; }", |ast| unsafe { - parse_func(ast) - }); - print_ast( - b"fn main() -> void { ;;;return (1 + (2)); }", - |ast| unsafe { parse_func(ast) }, - ); - print_ast( - b"fn main() -> void { return (1 + (2 * 3)) / 4; }", - |ast| unsafe { parse_func(ast) }, - ); - print_ast(b"fn main() -> void { return 1 + 2 * 3; }", |ast| unsafe { - parse_func(ast) - }); + // print_ast(b"3 + 4", |ast| unsafe { parse_expr(ast) }); + // print_ast(b"fn main() -> void { return 1 + 2; }", |ast| unsafe { + // parse_func(ast) + // }); + // print_ast( + // b"fn main() -> void { ;;;return (1 + (2)); }", + // |ast| unsafe { parse_func(ast) }, + // ); + // print_ast( + // b"fn main() -> void { return (1 + (2 * 3)) / 4; }", + // |ast| unsafe { parse_func(ast) }, + // ); + // print_ast(b"fn main() -> void { return 1 + 2 * 3; }", |ast| unsafe { + // parse_func(ast) + // }); + + // print_ast(b"fn main() -> void { let x: u32 = 4; }", |ast| unsafe { + // parse_func(ast) + // }); + // print_ast( + // b"fn main(a: u32) -> void { let x: u32 = a + 4; }", + // |ast| unsafe { parse_func(ast) }, + // ); + // print_ast( + // b"fn main(a: u32) -> void { + // let y: u32 = a + 4; + // let y: *u32 = &y; + // return *y; + // }", + // |ast| unsafe { parse_func(ast) }, + // ); + // print_ast( + // b"fn main(a: u32) -> void { + // let y: u32 = a + 4; + // { + // let y: u32 = 10; + // } + // let y: *u32 = &y; + // return *y; + // }", + // |ast| unsafe { parse_func(ast) }, + // ); + // print_ast( + // b"fn main(a: *u32, b: u32) -> void { + // *a = b; + // a = &b; + // }", + // |ast| unsafe { parse_func(ast) }, + // ); + + // print_ast( + // b"fn main(a: u32) -> void { + // if (a == 0) { + // return 1; + // } else { + // return 0; + // } + // }", + // |ast| unsafe { parse_func(ast) }, + // ); - print_ast(b"fn main() -> void { let x: u32 = 4; }", |ast| unsafe { - parse_func(ast) - }); - print_ast( - b"fn main(a: u32) -> void { let x: u32 = a + 4; }", - |ast| unsafe { parse_func(ast) }, - ); print_ast( b"fn main(a: u32) -> void { - let y: u32 = a + 4; - let y: *u32 = &y; - return *y; - }", - |ast| unsafe { parse_func(ast) }, - ); - print_ast( - b"fn main(a: u32) -> void { - let y: u32 = a + 4; - { - let y: u32 = 10; - } - let y: *u32 = &y; - return *y; - }", - |ast| unsafe { parse_func(ast) }, - ); - print_ast( - b"fn main(a: *u32, b: u32) -> void { -*a = b; -a = &b; -}", - |ast| unsafe { parse_func(ast) }, - ); - print_ast( - b"fn main(a: u32) -> void { - if (a == 0) { - return 1; - } else { - return 0; - } +return a(1,2); }", |ast| unsafe { parse_func(ast) }, ); diff --git a/lang/tests/shared/ast_debug.rs b/lang/tests/shared/ast_debug.rs index 6486af3..dd413b0 100644 --- a/lang/tests/shared/ast_debug.rs +++ b/lang/tests/shared/ast_debug.rs @@ -4,8 +4,8 @@ impl core::fmt::Display for util::defs::AstNode { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { use util::defs::{ BinaryExpr, AST_ADDRESS_OF, AST_ARG, AST_ASSIGNMENT, AST_BINARY_OP, AST_BLOCK, - AST_DEREF, AST_FUNCTION, AST_IF, AST_NUMBER, AST_PLACE_TO_VALUE, AST_RETURN_STATEMENT, - AST_VALUE_TO_PLACE, AST_VAR_DECL, AST_VAR_REF, + AST_CALL, AST_DEREF, AST_FUNCTION, AST_IF, AST_NUMBER, AST_PLACE_TO_VALUE, + AST_RETURN_STATEMENT, AST_VALUE_TO_PLACE, AST_VAR_DECL, AST_VAR_REF, }; match self.kind { AST_NUMBER => { @@ -17,6 +17,12 @@ impl core::fmt::Display for util::defs::AstNode { AST_ADDRESS_OF => { write!(f, "AddressOf(expr: {})", self.data as usize) } + AST_CALL => { + let call = unsafe { self.data.cast::().read() }; + write!(f, "Call(callee: {}, params: {:?})", call.callee, unsafe { + std::slice::from_raw_parts(call.params.cast::(), call.params_len as usize) + },) + } AST_ARG => { let arg = unsafe { self.data.cast::().read() }; write!( diff --git a/lang/tests/shared/defs.rs b/lang/tests/shared/defs.rs index d31e46f..3492017 100644 --- a/lang/tests/shared/defs.rs +++ b/lang/tests/shared/defs.rs @@ -4,6 +4,7 @@ unsafe extern "C" { pub unsafe fn parse_func(ast: *mut Ast) -> u64; pub unsafe fn parse_args(ast: *mut Ast) -> (*const u64, usize); + pub unsafe fn parse_postfix_expr(ast: *mut Ast) -> (u64, bool); pub unsafe fn parse_primary_expr(ast: *mut Ast) -> (u64, bool); pub unsafe fn parse_binary_expr(ast: *mut Ast, precedence: u8) -> (u64, bool); pub unsafe fn parse_expr(ast: *mut Ast) -> u64; @@ -190,6 +191,14 @@ pub struct AstFunction { pub body: u64, } +#[repr(C)] +#[derive(Debug)] +pub struct AstCallExpr { + pub callee: u64, + pub params: *const u64, + pub params_len: usize, +} + #[repr(C)] #[derive(Debug)] pub struct AstVarRef {