as expression (<prefix-expr> as <type>), more types in ast

This commit is contained in:
janis 2025-11-04 16:51:59 +01:00
parent 07dcaf6a64
commit 192c123373
Signed by: janis
SSH key fingerprint: SHA256:bB1qbbqmDXZNT0KKD5c2Dfjg53JGhj7B3CFcLIzSqq8
6 changed files with 217 additions and 18 deletions

View file

@ -315,6 +315,80 @@ parse_number:
.panic: .panic:
call panic call panic
;; rdi: *mut Ast
;; define-fn: fn parse_as_expr(ast: *mut Ast) -> (u64, bool)
parse_as_expr:
push rbp
mov rbp, rsp
; start-structs
; struct AstAsExpr {
; expr: u64,
; ty: Type,
; }
; end-structs
; Type [32..48]
; prefix_expr [16..32]
; span [8..16]
; ast [0..8]
sub rsp, 48
mov [rsp], rdi ; Ast
call parse_prefix_expr
mov [rsp + 16], rax ; prefix_expr
mov [rsp + 24], rdx ; placeness
call tokeniser_get_cursor
mov [rsp + 8], rax ; span
mov dil, TOKEN_AS
call expect_token
test rax, rax
jz .done
; convert prefix_expr to value
.as_expr:
mov rdi, [rsp] ; Ast
mov rsi, [rsp + 16] ; prefix_expr
mov dl, [rsp + 24] ; placeness
call ast_place_to_value
mov [rsp + 24], rax ; AstAsExpr.expr
; parse type
mov rdi, [rsp] ; Ast
call parse_type
mov [rsp + 32], rax ; AstAsExpr.Type.kind
mov [rsp + 40], rdx ; AstAsExpr.Type.data
mov rdi, 16 ; size_of::<AstAsExpr>
mov rsi, 8 ; align_of::<AstAsExpr>
call bump_alloc
mov rdi, rax ; dst
lea rsi, [rsp + 24] ; &AstAsExpr
mov rdx, 16 ; size_of::<AstAsExpr>
call memcpy
mov qword [rsp + 16], AST_AS ; AstNode.kind
mov [rsp + 24], rdi ; AstNode.data
mov qword [rsp + 32], 0 ; AstNode.extra
mov rdi, [rsp + 8] ; span
mov [rsp + 40], rdi ; AstNode.span
mov rdi, [rsp] ; Ast
lea rsi, [rsp + 16] ; &AstNode
call vec_push
; rax = index of pushed node
mov rdx, 0 ; placeness = false
jmp .epilogue
.done:
mov rax, [rsp + 16] ; prefix_expr
mov rdx, [rsp + 24] ; placeness
.epilogue:
add rsp, 48
pop rbp
ret
;; rdi: *mut Ast ;; rdi: *mut Ast
;; define-fn: fn parse_postfix_expr(ast: *mut Ast) -> (u64, bool) ;; define-fn: fn parse_postfix_expr(ast: *mut Ast) -> (u64, bool)
parse_postfix_expr: parse_postfix_expr:
@ -551,7 +625,7 @@ parse_binary_expr:
call tokeniser_get_cursor call tokeniser_get_cursor
mov [rsp + 56], rax ; span mov [rsp + 56], rax ; span
call parse_prefix_expr call parse_as_expr
mov [rsp + 8], rax ; left mov [rsp + 8], rax ; left
mov [rsp + 19], dl ; left_placeness mov [rsp + 19], dl ; left_placeness
@ -834,13 +908,63 @@ parse_type:
je .bool_type je .bool_type
cmp al, TOKEN_STAR cmp al, TOKEN_STAR
je .pointer_type je .pointer_type
cmp al, TOKEN_U8
je .u8_type
cmp al, TOKEN_I8
je .i8_type
cmp al, TOKEN_U16
je .u16_type
cmp al, TOKEN_I16
je .i16_type
cmp al, TOKEN_U64
je .u64_type
cmp al, TOKEN_I64
je .i64_type
cmp al, TOKEN_F32
je .f32_type
cmp al, TOKEN_F64
je .f64_type
cmp al, TOKEN_USIZE
je .usize_type
cmp al, TOKEN_ISIZE
je .isize_type
jmp .panic jmp .panic
.i32_type: .u8_type:
mov rax, TYPE_I32 mov rax, TYPE_U8
jmp .epilogue
.i8_type:
mov rax, TYPE_I8
jmp .epilogue
.u16_type:
mov rax, TYPE_U16
jmp .epilogue
.i16_type:
mov rax, TYPE_I16
jmp .epilogue jmp .epilogue
.u32_type: .u32_type:
mov rax, TYPE_U32 mov rax, TYPE_U32
jmp .epilogue jmp .epilogue
.i32_type:
mov rax, TYPE_I32
jmp .epilogue
.u64_type:
mov rax, TYPE_U64
jmp .epilogue
.i64_type:
mov rax, TYPE_I64
jmp .epilogue
.usize_type:
mov rax, TYPE_USIZE
jmp .epilogue
.isize_type:
mov rax, TYPE_ISIZE
jmp .epilogue
.f32_type:
mov rax, TYPE_F32
jmp .epilogue
.f64_type:
mov rax, TYPE_F64
jmp .epilogue
.void_type: .void_type:
mov rax, TYPE_VOID mov rax, TYPE_VOID
jmp .epilogue jmp .epilogue

View file

@ -18,11 +18,22 @@ section .rdata
AST_IF equ 16 ; :u8 AST_IF equ 16 ; :u8
AST_ELSE equ 17 ; :u8 AST_ELSE equ 17 ; :u8
AST_CALL equ 18 ; :u8 AST_CALL equ 18 ; :u8
AST_AS equ 19 ; :u8
TYPE_VOID equ 1 ; :u8 TYPE_VOID equ 1 ; :u8
TYPE_BOOL equ 2 ; :u8 TYPE_BOOL equ 2 ; :u8
TYPE_I32 equ 3 ; :u8 TYPE_U8 equ 3 ; :u8
TYPE_U32 equ 4 ; :u8 TYPE_U16 equ 4 ; :u8
TYPE_STR equ 5 ; :u8 TYPE_U32 equ 5 ; :u8
TYPE_POINTER equ 6 ; :u8 TYPE_U64 equ 6 ; :u8
TYPE_USIZE equ 7 ; :u8
TYPE_I8 equ 8 ; :u8
TYPE_I16 equ 9 ; :u8
TYPE_I32 equ 10 ; :u8
TYPE_I64 equ 11 ; :u8
TYPE_ISIZE equ 12 ; :u8
TYPE_STR equ 13 ; :u8
TYPE_POINTER equ 14 ; :u8
TYPE_F32 equ 15 ; :u8
TYPE_F64 equ 16 ; :u8
;; end-consts ;; end-consts

View file

@ -127,6 +127,13 @@ fn main() {
print_ast( print_ast(
b"fn main(a: u32) -> void { b"fn main(a: u32) -> void {
return main(1); return main(1);
}",
|ast| unsafe { parse_func(ast) },
);
print_ast(
b"fn main(a: u32) -> void {
return 1 as u8;
}", }",
|ast| unsafe { parse_func(ast) }, |ast| unsafe { parse_func(ast) },
); );

View file

@ -3,7 +3,7 @@ use super::util;
impl core::fmt::Display for util::defs::AstNode { 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_AS, AST_ASSIGNMENT, AST_BINARY_OP, AST_BLOCK,
AST_CALL, AST_DEREF, AST_FUNCTION, AST_IF, AST_NUMBER, AST_PLACE_TO_VALUE, 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, AST_RETURN_STATEMENT, AST_VALUE_TO_PLACE, AST_VAR_DECL, AST_VAR_REF,
}; };
@ -23,6 +23,10 @@ impl core::fmt::Display for util::defs::AstNode {
std::slice::from_raw_parts(call.params.cast::<u64>(), call.params_len as usize) std::slice::from_raw_parts(call.params.cast::<u64>(), call.params_len as usize)
},) },)
} }
AST_AS => {
let as_expr = unsafe { self.data.cast::<util::defs::AstAsExpr>().read() };
write!(f, "As(expr: {}, target_type: {})", as_expr.expr, as_expr.ty)
}
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!(

View file

@ -6,6 +6,7 @@ unsafe extern "C" {
pub unsafe fn bump_alloc(size: usize, alignment: usize) -> *mut u8; pub unsafe fn bump_alloc(size: usize, alignment: usize) -> *mut u8;
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_as_expr(ast: *mut Ast) -> (u64, bool);
pub unsafe fn parse_postfix_expr(ast: *mut Ast) -> (u64, bool); 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);
@ -64,12 +65,23 @@ pub const AST_SWITCH: u8 = 15;
pub const AST_IF: u8 = 16; pub const AST_IF: u8 = 16;
pub const AST_ELSE: u8 = 17; pub const AST_ELSE: u8 = 17;
pub const AST_CALL: u8 = 18; pub const AST_CALL: u8 = 18;
pub const AST_AS: u8 = 19;
pub const TYPE_VOID: u8 = 1; pub const TYPE_VOID: u8 = 1;
pub const TYPE_BOOL: u8 = 2; pub const TYPE_BOOL: u8 = 2;
pub const TYPE_I32: u8 = 3; pub const TYPE_U8: u8 = 3;
pub const TYPE_U32: u8 = 4; pub const TYPE_U16: u8 = 4;
pub const TYPE_STR: u8 = 5; pub const TYPE_U32: u8 = 5;
pub const TYPE_POINTER: u8 = 6; pub const TYPE_U64: u8 = 6;
pub const TYPE_USIZE: u8 = 7;
pub const TYPE_I8: u8 = 8;
pub const TYPE_I16: u8 = 9;
pub const TYPE_I32: u8 = 10;
pub const TYPE_I64: u8 = 11;
pub const TYPE_ISIZE: u8 = 12;
pub const TYPE_STR: u8 = 13;
pub const TYPE_POINTER: u8 = 14;
pub const TYPE_F32: u8 = 15;
pub const TYPE_F64: u8 = 16;
pub const OPERAND_REGISTER: u32 = 1; pub const OPERAND_REGISTER: u32 = 1;
pub const OPERAND_RBP_VALUE: u32 = 2; pub const OPERAND_RBP_VALUE: u32 = 2;
pub const OPERAND_RBP_PVALUE: u32 = 3; pub const OPERAND_RBP_PVALUE: u32 = 3;
@ -195,6 +207,13 @@ pub struct AstFunction {
pub body: u64, pub body: u64,
} }
#[repr(C)]
#[derive(Debug)]
pub struct AstAsExpr {
pub expr: u64,
pub ty: Type,
}
#[repr(C)] #[repr(C)]
#[derive(Debug)] #[derive(Debug)]
pub struct AstCallExpr { pub struct AstCallExpr {

View file

@ -373,26 +373,60 @@ impl<'a, T: core::fmt::Display> core::fmt::Display for DisplaySlice<'a, T> {
impl core::fmt::Display for defs::Type { impl core::fmt::Display for defs::Type {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
use defs::{
TYPE_BOOL, TYPE_F32, TYPE_F64, TYPE_I16, TYPE_I32, TYPE_I64, TYPE_I8, TYPE_ISIZE,
TYPE_POINTER, TYPE_STR, TYPE_U16, TYPE_U32, TYPE_U64, TYPE_U8, TYPE_USIZE, TYPE_VOID,
};
match self.kind { match self.kind {
defs::TYPE_VOID => { TYPE_VOID => {
write!(f, "void") write!(f, "void")
} }
defs::TYPE_BOOL => { TYPE_BOOL => {
write!(f, "bool") write!(f, "bool")
} }
defs::TYPE_I32 => { TYPE_I32 => {
write!(f, "i32") write!(f, "i32")
} }
defs::TYPE_U32 => { TYPE_U32 => {
write!(f, "u32") write!(f, "u32")
} }
defs::TYPE_STR => { TYPE_STR => {
write!(f, "str") write!(f, "str")
} }
defs::TYPE_POINTER => { TYPE_POINTER => {
let pointee = unsafe { (self.data as *const defs::Type).read() }; let pointee = unsafe { (self.data as *const defs::Type).read() };
write!(f, "*{pointee}",) write!(f, "*{pointee}",)
} }
TYPE_I8 => {
write!(f, "i8")
}
TYPE_U8 => {
write!(f, "u8")
}
TYPE_I16 => {
write!(f, "i16")
}
TYPE_U16 => {
write!(f, "u16")
}
TYPE_I64 => {
write!(f, "i64")
}
TYPE_U64 => {
write!(f, "u64")
}
TYPE_F32 => {
write!(f, "f32")
}
TYPE_F64 => {
write!(f, "f64")
}
TYPE_USIZE => {
write!(f, "usize")
}
TYPE_ISIZE => {
write!(f, "isize")
}
_ => { _ => {
write!(f, "UnknownType") write!(f, "UnknownType")
} }