diff --git a/lang/src/ast.asm b/lang/src/ast.asm index 8017761..040bde1 100644 --- a/lang/src/ast.asm +++ b/lang/src/ast.asm @@ -3,6 +3,7 @@ default rel %include "src/tokeniser.inc" section .rdata +;; start-constants AST_FUNCTION equ 1 AST_BLOCK equ 2 AST_VARIABLE equ 3 @@ -15,6 +16,7 @@ section .rdata TYPE_I32 equ 3 TYPE_U32 equ 4 TYPE_STR equ 5 +;; end-constants section .text extern vec_init_with @@ -36,7 +38,16 @@ extern peek_expect_token extern str_to_int +global parse_func +global parse_args +global parse_expr +global parse_binary_expr +global parse_primary_expr +global parse_statement +global parse_block + ;; start very simple, with only functions and addition +;; start-structs ;; struct Ast { ;; nodes: Vec, ;; } @@ -55,9 +66,10 @@ extern str_to_int ;; struct Type { ;; kind: u8, ;; } +;; end-structs ;; rdi: *mut Ast -;; fn parse_func(ast: *mut Ast) -> u64 +;; define-fn: fn parse_func(ast: *mut Ast) -> u64 parse_func: push rbp mov rbp, rsp @@ -98,6 +110,7 @@ parse_func: mov [rsp + 40], rax ; body .epilogue: mov rdi, 48 + mov rsi, 8 call bump_alloc mov rsi, rsp mov rdi, rax @@ -110,6 +123,7 @@ parse_func: call vec_push mov rax, [rsp + 48] ; Ast mov rax, [rdi + 8] ; return Ast.nodes.len() + dec rax add rsp, 48 pop rdi pop rbp @@ -125,7 +139,7 @@ parse_func: call panic ;; rdi: *mut Ast -;; fn parse_args(ast: *mut Ast) -> (*const Argument, usize) +;; define-fn: fn parse_args(ast: *mut Ast) -> (*const Argument, usize) parse_args: push rbp mov rbp, rsp @@ -229,27 +243,27 @@ parse_number: parse_primary_expr: push rbp mov rbp, rsp - sub rsp, 8 + sub rsp, 24 mov [rsp], rdi ; Ast mov dil, TOKEN_NUMBER call expect_token test rax, rax - jz .number + jnz .number jmp .panic .number: mov rdi, rax ; lexeme ptr mov rsi, rdx ; lexeme len call parse_number - mov rdi, [rsp] - push rdi - mov byte [rsp], AST_NUMBER ; kind - mov [rsp + 8], rax ; data - lea rsi, [rsp] + mov rdi, [rsp] ; Ast + mov byte [rsp + 8], AST_NUMBER ; kind + mov [rsp + 16], rax ; data + lea rsi, [rsp + 8] ; AstNode call vec_push - pop rdi - mov rax, [rdi + 8] ; return Ast.nodes.len() - add rsp, 8 + mov rdi, [rsp] ; Ast + mov rax, [rdi + 8] ; return Ast.nodes.len() + dec rax + add rsp, 24 pop rbp ret .panic: @@ -262,6 +276,14 @@ parse_primary_expr: parse_binary_expr: push rbp mov rbp, rsp + + ; size: 24, align: 8 + ; struct BinaryExpr { + ; left: u64, + ; operator: u8, + ; right: u64, + ; } + sub rsp, 64 ; lexeme: Lexeme [32..56] ; right: u64 [24..32] @@ -269,6 +291,7 @@ parse_binary_expr: ; operator: u8 [16..17] ; left: u64 [8..16] ; rdi: *mut Ast [0..8] + mov [rsp], rdi ; Ast mov byte [rsp + 17], sil ; upper_precedence mov byte [rsp + 16], 0 @@ -299,19 +322,30 @@ parse_binary_expr: call parse_binary_expr mov [rsp + 24], rax ; right - mov byte [rsp + 32], AST_BINARY_OP ; kind - lea rax, [rsp + 8] - mov [rsp + 40], rax ; data ptr + mov rdi, 24 + mov rsi, 8 + call bump_alloc + mov rdx, [rsp + 8] ; left + mov [rax + 0], rdx ; left + mov dl, byte [rsp + 16] ; operator + mov byte [rax + 8], dl ; operator + mov rdx, [rsp + 24] ; right + mov [rax + 16], rdx ; right + + mov byte [rsp + 32], AST_BINARY_OP ; AstNode.kind + mov [rsp + 40], rax ; AstNode.data mov rdi, [rsp] ; Ast - lea rsi, [rsp + 32] ; AstNode + lea rsi, [rsp + 32] ; &AstNode call vec_push mov rdi, [rsp] ; Ast mov rax, [rdi + 8] ; Ast.nodes.len() + dec rax mov [rsp + 8], rax ; left + jmp .loop .done: mov rax, [rsp + 8] ; left - add rsp, 56 + add rsp, 64 pop rbp ret @@ -323,6 +357,11 @@ parse_expr: mov rbp, rsp sub rsp, 8 mov [rsp], rdi ; Ast + mov sil, 0 + call parse_binary_expr + add rsp, 8 + pop rbp + ret ;; rdi: *mut Ast ;; fn parse_statement(ast: *mut Ast) -> u64 @@ -345,10 +384,11 @@ parse_statement: lea rax, [rsp + 16] ; data ptr mov [rsp + 8], rax ; data mov rdi, [rsp + 24] ; Ast - mov rsi, rsp ; AstNode + mov rsi, rsp ; AstNode call vec_push mov rdi, [rsp + 24] ; Ast mov rax, [rdi + 8] ; Ast.nodes.len() + dec rax mov [rsp], rax mov dil, TOKEN_SEMI @@ -393,6 +433,7 @@ parse_block: call vec_push mov rdi, [rsp + 56] ; Ast mov rax, [rdi + 8] ; Ast.nodes.len() + dec rax add rsp, 56 pop rdi pop rbp diff --git a/lang/tests/ast.rs b/lang/tests/ast.rs index 7f7b9b4..7a008d4 100644 --- a/lang/tests/ast.rs +++ b/lang/tests/ast.rs @@ -3,7 +3,7 @@ mod util; #[repr(C)] struct Ast { - nodes: util::BlobVec, + nodes: util::vec::Vec, } #[repr(C)] @@ -14,17 +14,25 @@ struct Argument { } #[repr(C)] +#[derive(Debug)] struct AstNode { node_type: u8, data: usize, } +use util::FFISlice; + unsafe extern "C" { unsafe fn bump_init(); unsafe fn parse_func(ast: *mut Ast) -> u64; - unsafe fn parse_args(ast: *mut Ast) -> (*const Argument, usize); - unsafe fn tokeniser_init(path: *const i8) -> (); + unsafe fn parse_args(ast: *mut Ast) -> FFISlice; + unsafe fn parse_expr(ast: *mut Ast) -> u64; + unsafe fn parse_binary_expr(ast: *mut Ast) -> u64; + unsafe fn parse_primary_expr(ast: *mut Ast) -> u64; + unsafe fn parse_statement(ast: *mut Ast) -> u64; + unsafe fn parse_block(ast: *mut Ast) -> u64; + unsafe fn tokeniser_init_buf(bytes: *const u8, len: usize) -> (); } fn main() { @@ -32,4 +40,16 @@ fn main() { bump_init(); } println!("Bump allocator initialized."); + + let src = b"3 + 4"; + + unsafe { + tokeniser_init_buf(src.as_ptr(), src.len()); + let mut ast = Ast { + nodes: util::vec::Vec::new(), + }; + let expr_id = parse_expr(&mut ast); + println!("Parsed expression with ID: {}", expr_id); + println!("{:#?}", ast.nodes.as_slice()); + } }