parsing function call

This commit is contained in:
janis 2025-11-03 21:24:02 +01:00
parent a90a01bc28
commit 9abd3f0f69
Signed by: janis
SSH key fingerprint: SHA256:bB1qbbqmDXZNT0KKD5c2Dfjg53JGhj7B3CFcLIzSqq8
4 changed files with 197 additions and 62 deletions

View file

@ -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::<AstCallExpr>
mov rsi, 8 ; align_of::<AstCallExpr>
call bump_alloc
mov rdi, rax ; dst
lea rsi, [rsp + 16] ; &callee
mov rdx, 24 ; size_of::<AstCallExpr>
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

View file

@ -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) },
);

View file

@ -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::<util::defs::AstCallExpr>().read() };
write!(f, "Call(callee: {}, params: {:?})", call.callee, unsafe {
std::slice::from_raw_parts(call.params.cast::<u64>(), call.params_len as usize)
},)
}
AST_ARG => {
let arg = unsafe { self.data.cast::<util::defs::AstArgument>().read() };
write!(

View file

@ -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 {