can parse basic function

This commit is contained in:
janis 2025-10-29 23:17:02 +01:00
parent 8740fea99d
commit d2597d2de7
Signed by: janis
SSH key fingerprint: SHA256:bB1qbbqmDXZNT0KKD5c2Dfjg53JGhj7B3CFcLIzSqq8
4 changed files with 81 additions and 24 deletions

View file

@ -77,6 +77,18 @@ parse_func:
push rbp push rbp
mov rbp, rsp mov rbp, rsp
push rdi 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 sub rsp, 48
; name: *const u8 [0..8] ; name: *const u8 [0..8]
; name_len: usize [8..16] ; name_len: usize [8..16]
@ -380,17 +392,16 @@ parse_statement:
mov dil, TOKEN_RETURN mov dil, TOKEN_RETURN
call expect_token call expect_token
test rax, rax test rax, rax
jz .return jnz .return
jmp .panic jmp .panic
.return: .return:
mov rdi, [rsp + 24] ; Ast
call parse_expr call parse_expr
mov [rsp + 16], rax ; expression
mov byte [rsp], AST_RETURN_STATEMENT ; kind mov byte [rsp], AST_RETURN_STATEMENT ; kind
lea rax, [rsp + 16] ; data ptr
mov [rsp + 8], rax ; data mov [rsp + 8], rax ; data
mov rdi, [rsp + 24] ; Ast mov rdi, [rsp + 24] ; Ast
mov rsi, rsp ; AstNode lea rsi, [rsp] ; AstNode
call vec_push call vec_push
mov rdi, [rsp + 24] ; Ast mov rdi, [rsp + 24] ; Ast
mov rax, [rdi + 8] ; Ast.nodes.len() mov rax, [rdi + 8] ; Ast.nodes.len()
@ -411,7 +422,6 @@ parse_statement:
parse_block: parse_block:
push rbp push rbp
mov rbp, rsp mov rbp, rsp
push rdi
; start-structs ; start-structs
; struct Block { ; struct Block {
@ -420,31 +430,46 @@ parse_block:
; } ; }
; end-structs ; end-structs
sub rsp, 56 ; Ast: *mut Ast [56..64]
; statements: Vec<Statement> [0..40] ; statements: Vec<Statement> [8..56]
; statement: u64 [40..48] ; statement: u64 [0..8]
sub rsp, 64
mov [rsp + 56], rdi ; Ast
mov dil, TOKEN_LBRACE mov dil, TOKEN_LBRACE
call unwrap_token call unwrap_token
.loop:
mov rdi, [rsp + 16] ; Ast mov dil, TOKEN_RBRACE
call parse_statement call peek_expect_token
test rax, rax test rax, rax
je .done jnz .done
lea rdi, [rsp + 16] ; vec
mov [rsp + 8], rax ; statement lea rdi, [rsp + 8]
lea rsi, [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 call vec_push
jmp .loop jmp .loop
.done: .done:
mov rdi, [rsp + 56] ; Ast mov rdi, [rsp + 56] ; Ast
lea rsi, [rsp + 16] ; statements vec-slice lea rsi, [rsp + 8] ; statements vec-slice
call vec_push call vec_push
mov rdi, [rsp + 56] ; Ast mov rdi, [rsp + 56] ; Ast
mov rax, [rdi + 8] ; Ast.nodes.len() mov rax, [rdi + 8] ; Ast.nodes.len()
dec rax dec rax
add rsp, 56 add rsp, 64
pop rdi
pop rbp pop rbp
ret ret

View file

@ -557,11 +557,13 @@ unwrap_token:
.panic: .panic:
call panic call panic
;; returns 0 if token not found, else returns lexeme (ptr, len)
;; dil: expected token ;; dil: expected token
peek_expect_token: peek_expect_token:
push rbp push rbp
mov rbp, rsp mov rbp, rsp
push qword [rel cursor] mov rax, [rel cursor]
push rax
call expect_token call expect_token
pop rdi pop rdi
mov [rel cursor], rdi mov [rel cursor], rdi
@ -573,7 +575,8 @@ peek_lexeme:
push rbp push rbp
mov rbp, rsp mov rbp, rsp
push rdi push rdi
push qword [rel cursor] ; save cursor mov rax, [rel cursor] ; current cursor
push rax
call find_lexeme call find_lexeme
pop rdi pop rdi
mov [rel cursor], rdi ; restore cursor mov [rel cursor], rdi ; restore cursor

View file

@ -7,7 +7,7 @@ unsafe extern "C" {
unsafe fn tokeniser_init_buf(bytes: *const u8, len: usize) -> (); 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() { fn main() {
unsafe { unsafe {
@ -39,7 +39,9 @@ fn main() {
impl std::fmt::Display for AstNode { impl std::fmt::Display for AstNode {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 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 { match self.kind as u32 {
AST_NUMBER => { AST_NUMBER => {
write!(f, "Number({})", self.data as usize) write!(f, "Number({})", self.data as usize)
@ -56,6 +58,22 @@ impl std::fmt::Display for AstNode {
operator, left, right 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::<util::defs::AstFunction>().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"), _ => write!(f, "UnknownNode"),
} }
} }

View file

@ -86,6 +86,17 @@ pub struct Type {
pub kind: u8, 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)] #[repr(C)]
#[derive(Debug)] #[derive(Debug)]
pub struct BinaryExpr { pub struct BinaryExpr {