as expression (<prefix-expr> as <type>), more types in ast
This commit is contained in:
parent
07dcaf6a64
commit
192c123373
130
lang/src/ast.asm
130
lang/src/ast.asm
|
|
@ -315,6 +315,80 @@ parse_number:
|
|||
.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
|
||||
;; define-fn: fn parse_postfix_expr(ast: *mut Ast) -> (u64, bool)
|
||||
parse_postfix_expr:
|
||||
|
|
@ -551,7 +625,7 @@ parse_binary_expr:
|
|||
call tokeniser_get_cursor
|
||||
mov [rsp + 56], rax ; span
|
||||
|
||||
call parse_prefix_expr
|
||||
call parse_as_expr
|
||||
mov [rsp + 8], rax ; left
|
||||
mov [rsp + 19], dl ; left_placeness
|
||||
|
||||
|
|
@ -834,13 +908,63 @@ parse_type:
|
|||
je .bool_type
|
||||
cmp al, TOKEN_STAR
|
||||
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
|
||||
.i32_type:
|
||||
mov rax, TYPE_I32
|
||||
.u8_type:
|
||||
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
|
||||
.u32_type:
|
||||
mov rax, TYPE_U32
|
||||
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:
|
||||
mov rax, TYPE_VOID
|
||||
jmp .epilogue
|
||||
|
|
|
|||
|
|
@ -18,11 +18,22 @@ section .rdata
|
|||
AST_IF equ 16 ; :u8
|
||||
AST_ELSE equ 17 ; :u8
|
||||
AST_CALL equ 18 ; :u8
|
||||
AST_AS equ 19 ; :u8
|
||||
|
||||
TYPE_VOID equ 1 ; :u8
|
||||
TYPE_BOOL equ 2 ; :u8
|
||||
TYPE_I32 equ 3 ; :u8
|
||||
TYPE_U32 equ 4 ; :u8
|
||||
TYPE_STR equ 5 ; :u8
|
||||
TYPE_POINTER equ 6 ; :u8
|
||||
TYPE_U8 equ 3 ; :u8
|
||||
TYPE_U16 equ 4 ; :u8
|
||||
TYPE_U32 equ 5 ; :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
|
||||
|
|
|
|||
|
|
@ -127,6 +127,13 @@ fn main() {
|
|||
print_ast(
|
||||
b"fn main(a: u32) -> void {
|
||||
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) },
|
||||
);
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ use super::util;
|
|||
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,
|
||||
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_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)
|
||||
},)
|
||||
}
|
||||
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 => {
|
||||
let arg = unsafe { self.data.cast::<util::defs::AstArgument>().read() };
|
||||
write!(
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ unsafe extern "C" {
|
|||
pub unsafe fn bump_alloc(size: usize, alignment: usize) -> *mut u8;
|
||||
pub unsafe fn parse_func(ast: *mut Ast) -> u64;
|
||||
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_primary_expr(ast: *mut Ast) -> (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_ELSE: u8 = 17;
|
||||
pub const AST_CALL: u8 = 18;
|
||||
pub const AST_AS: u8 = 19;
|
||||
pub const TYPE_VOID: u8 = 1;
|
||||
pub const TYPE_BOOL: u8 = 2;
|
||||
pub const TYPE_I32: u8 = 3;
|
||||
pub const TYPE_U32: u8 = 4;
|
||||
pub const TYPE_STR: u8 = 5;
|
||||
pub const TYPE_POINTER: u8 = 6;
|
||||
pub const TYPE_U8: u8 = 3;
|
||||
pub const TYPE_U16: u8 = 4;
|
||||
pub const TYPE_U32: u8 = 5;
|
||||
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_RBP_VALUE: u32 = 2;
|
||||
pub const OPERAND_RBP_PVALUE: u32 = 3;
|
||||
|
|
@ -195,6 +207,13 @@ pub struct AstFunction {
|
|||
pub body: u64,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Debug)]
|
||||
pub struct AstAsExpr {
|
||||
pub expr: u64,
|
||||
pub ty: Type,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Debug)]
|
||||
pub struct AstCallExpr {
|
||||
|
|
|
|||
|
|
@ -373,26 +373,60 @@ impl<'a, T: core::fmt::Display> core::fmt::Display for DisplaySlice<'a, T> {
|
|||
|
||||
impl core::fmt::Display for defs::Type {
|
||||
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 {
|
||||
defs::TYPE_VOID => {
|
||||
TYPE_VOID => {
|
||||
write!(f, "void")
|
||||
}
|
||||
defs::TYPE_BOOL => {
|
||||
TYPE_BOOL => {
|
||||
write!(f, "bool")
|
||||
}
|
||||
defs::TYPE_I32 => {
|
||||
TYPE_I32 => {
|
||||
write!(f, "i32")
|
||||
}
|
||||
defs::TYPE_U32 => {
|
||||
TYPE_U32 => {
|
||||
write!(f, "u32")
|
||||
}
|
||||
defs::TYPE_STR => {
|
||||
TYPE_STR => {
|
||||
write!(f, "str")
|
||||
}
|
||||
defs::TYPE_POINTER => {
|
||||
TYPE_POINTER => {
|
||||
let pointee = unsafe { (self.data as *const defs::Type).read() };
|
||||
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")
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue