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_binary_expr
|
||||||
global parse_primary_expr
|
global parse_primary_expr
|
||||||
global parse_if_expr
|
global parse_if_expr
|
||||||
|
global parse_postfix_expr
|
||||||
global parse_statement
|
global parse_statement
|
||||||
global parse_block
|
global parse_block
|
||||||
global ast_build_symtable
|
global ast_build_symtable
|
||||||
|
|
@ -314,6 +315,117 @@ parse_number:
|
||||||
.panic:
|
.panic:
|
||||||
call 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
|
;; rdi: *mut Ast
|
||||||
;; define-fn: fn parse_primary_expr(ast: *mut Ast) -> (u64, bool)
|
;; define-fn: fn parse_primary_expr(ast: *mut Ast) -> (u64, bool)
|
||||||
parse_primary_expr:
|
parse_primary_expr:
|
||||||
|
|
@ -463,11 +575,11 @@ parse_binary_expr:
|
||||||
cmove bx, word [rel PRECEDENCE_EQ]
|
cmove bx, word [rel PRECEDENCE_EQ]
|
||||||
cmp al, TOKEN_LT
|
cmp al, TOKEN_LT
|
||||||
cmove bx, word [rel PRECEDENCE_CMP]
|
cmove bx, word [rel PRECEDENCE_CMP]
|
||||||
cmp al, TOKEN_LTEQ
|
cmp al, TOKEN_LEQ
|
||||||
cmove bx, word [rel PRECEDENCE_CMP]
|
cmove bx, word [rel PRECEDENCE_CMP]
|
||||||
cmp al, TOKEN_GT
|
cmp al, TOKEN_GT
|
||||||
cmove bx, word [rel PRECEDENCE_CMP]
|
cmove bx, word [rel PRECEDENCE_CMP]
|
||||||
cmp al, TOKEN_GTEQ
|
cmp al, TOKEN_GEQ
|
||||||
cmove bx, word [rel PRECEDENCE_CMP]
|
cmove bx, word [rel PRECEDENCE_CMP]
|
||||||
cmp bx, -1
|
cmp bx, -1
|
||||||
je .done
|
je .done
|
||||||
|
|
@ -782,7 +894,7 @@ parse_prefix_expr:
|
||||||
jnz .address_of
|
jnz .address_of
|
||||||
|
|
||||||
mov rdi, [rsp] ; Ast
|
mov rdi, [rsp] ; Ast
|
||||||
call parse_primary_expr
|
call parse_postfix_expr
|
||||||
jmp .done
|
jmp .done
|
||||||
.dereference:
|
.dereference:
|
||||||
mov rdi, [rsp] ; Ast
|
mov rdi, [rsp] ; Ast
|
||||||
|
|
|
||||||
|
|
@ -58,67 +58,75 @@ fn main() {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
print_ast(
|
// print_ast(
|
||||||
b"fn main() -> void { return 1 * 2 + 3 * 4; }",
|
// b"fn main() -> void { return 1 * 2 + 3 * 4; }",
|
||||||
|ast| unsafe { parse_func(ast) },
|
// |ast| unsafe { parse_func(ast) },
|
||||||
);
|
// );
|
||||||
|
|
||||||
print_ast(b"3 + 4", |ast| unsafe { parse_expr(ast) });
|
// print_ast(b"3 + 4", |ast| unsafe { parse_expr(ast) });
|
||||||
print_ast(b"fn main() -> void { return 1 + 2; }", |ast| unsafe {
|
// print_ast(b"fn main() -> void { return 1 + 2; }", |ast| unsafe {
|
||||||
parse_func(ast)
|
// parse_func(ast)
|
||||||
});
|
// });
|
||||||
print_ast(
|
// print_ast(
|
||||||
b"fn main() -> void { ;;;return (1 + (2)); }",
|
// b"fn main() -> void { ;;;return (1 + (2)); }",
|
||||||
|ast| unsafe { parse_func(ast) },
|
// |ast| unsafe { parse_func(ast) },
|
||||||
);
|
// );
|
||||||
print_ast(
|
// print_ast(
|
||||||
b"fn main() -> void { return (1 + (2 * 3)) / 4; }",
|
// b"fn main() -> void { return (1 + (2 * 3)) / 4; }",
|
||||||
|ast| unsafe { parse_func(ast) },
|
// |ast| unsafe { parse_func(ast) },
|
||||||
);
|
// );
|
||||||
print_ast(b"fn main() -> void { return 1 + 2 * 3; }", |ast| unsafe {
|
// print_ast(b"fn main() -> void { return 1 + 2 * 3; }", |ast| unsafe {
|
||||||
parse_func(ast)
|
// 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(
|
print_ast(
|
||||||
b"fn main(a: u32) -> void {
|
b"fn main(a: u32) -> void {
|
||||||
let y: u32 = a + 4;
|
return a(1,2);
|
||||||
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) },
|
|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 {
|
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||||
use util::defs::{
|
use util::defs::{
|
||||||
BinaryExpr, AST_ADDRESS_OF, AST_ARG, AST_ASSIGNMENT, AST_BINARY_OP, AST_BLOCK,
|
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_CALL, AST_DEREF, AST_FUNCTION, AST_IF, AST_NUMBER, AST_PLACE_TO_VALUE,
|
||||||
AST_VALUE_TO_PLACE, AST_VAR_DECL, AST_VAR_REF,
|
AST_RETURN_STATEMENT, AST_VALUE_TO_PLACE, AST_VAR_DECL, AST_VAR_REF,
|
||||||
};
|
};
|
||||||
match self.kind {
|
match self.kind {
|
||||||
AST_NUMBER => {
|
AST_NUMBER => {
|
||||||
|
|
@ -17,6 +17,12 @@ impl core::fmt::Display for util::defs::AstNode {
|
||||||
AST_ADDRESS_OF => {
|
AST_ADDRESS_OF => {
|
||||||
write!(f, "AddressOf(expr: {})", self.data as usize)
|
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 => {
|
AST_ARG => {
|
||||||
let arg = unsafe { self.data.cast::<util::defs::AstArgument>().read() };
|
let arg = unsafe { self.data.cast::<util::defs::AstArgument>().read() };
|
||||||
write!(
|
write!(
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@
|
||||||
unsafe extern "C" {
|
unsafe extern "C" {
|
||||||
pub unsafe fn parse_func(ast: *mut Ast) -> u64;
|
pub unsafe fn parse_func(ast: *mut Ast) -> u64;
|
||||||
pub unsafe fn parse_args(ast: *mut Ast) -> (*const u64, usize);
|
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_primary_expr(ast: *mut Ast) -> (u64, bool);
|
||||||
pub unsafe fn parse_binary_expr(ast: *mut Ast, precedence: u8) -> (u64, bool);
|
pub unsafe fn parse_binary_expr(ast: *mut Ast, precedence: u8) -> (u64, bool);
|
||||||
pub unsafe fn parse_expr(ast: *mut Ast) -> u64;
|
pub unsafe fn parse_expr(ast: *mut Ast) -> u64;
|
||||||
|
|
@ -190,6 +191,14 @@ pub struct AstFunction {
|
||||||
pub body: u64,
|
pub body: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct AstCallExpr {
|
||||||
|
pub callee: u64,
|
||||||
|
pub params: *const u64,
|
||||||
|
pub params_len: usize,
|
||||||
|
}
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct AstVarRef {
|
pub struct AstVarRef {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue