parsing function call
This commit is contained in:
parent
a90a01bc28
commit
9abd3f0f69
118
lang/src/ast.asm
118
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::<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
|
||||
|
|
|
|||
|
|
@ -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) },
|
||||
);
|
||||
|
|
|
|||
|
|
@ -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!(
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
Loading…
Reference in a new issue