args, var-ref
This commit is contained in:
parent
84e87824ba
commit
e54313b6a2
121
lang/src/ast.asm
121
lang/src/ast.asm
|
|
@ -4,19 +4,20 @@ default rel
|
|||
|
||||
section .rdata
|
||||
;; start-consts
|
||||
AST_FUNCTION equ 1
|
||||
AST_BLOCK equ 2
|
||||
AST_VARIABLE equ 3
|
||||
AST_NUMBER equ 4
|
||||
AST_BINARY_OP equ 5
|
||||
AST_RETURN_STATEMENT equ 6
|
||||
AST_VALUE_TO_PLACE equ 7
|
||||
AST_PLACE_TO_VALUE equ 8
|
||||
AST_ASSIGNMENT equ 9
|
||||
AST_DEREF equ 10
|
||||
AST_ADDRESS_OF equ 11
|
||||
AST_VAR_DECL equ 12
|
||||
AST_VAR_REF equ 13
|
||||
AST_FUNCTION equ 1 ; :u8
|
||||
AST_BLOCK equ 2 ; :u8
|
||||
AST_VARIABLE equ 3 ; :u8
|
||||
AST_NUMBER equ 4 ; :u8
|
||||
AST_BINARY_OP equ 5 ; :u8
|
||||
AST_RETURN_STATEMENT equ 6 ; :u8
|
||||
AST_VALUE_TO_PLACE equ 7 ; :u8
|
||||
AST_PLACE_TO_VALUE equ 8 ; :u8
|
||||
AST_ASSIGNMENT equ 9 ; :u8
|
||||
AST_DEREF equ 10 ; :u8
|
||||
AST_ADDRESS_OF equ 11 ; :u8
|
||||
AST_VAR_DECL equ 12 ; :u8
|
||||
AST_VAR_REF equ 13 ; :u8
|
||||
AST_ARG equ 14 ; :u8
|
||||
|
||||
TYPE_VOID equ 1
|
||||
TYPE_BOOL equ 2
|
||||
|
|
@ -77,7 +78,7 @@ global parse_block
|
|||
;; extra: usize,
|
||||
;; }
|
||||
;;
|
||||
;; struct Argument {
|
||||
;; struct AstArgument {
|
||||
;; name: *const u8,
|
||||
;; name_len: usize,
|
||||
;; arg_type: Type,
|
||||
|
|
@ -99,7 +100,7 @@ parse_func:
|
|||
; struct AstFunction {
|
||||
; name: *const u8,
|
||||
; name_len: usize,
|
||||
; args: *const Argument,
|
||||
; args: *const u64,
|
||||
; args_len: usize,
|
||||
; return_type: Type,
|
||||
; body: u64,
|
||||
|
|
@ -172,15 +173,18 @@ parse_func:
|
|||
call panic
|
||||
|
||||
;; rdi: *mut Ast
|
||||
;; define-fn: fn parse_args(ast: *mut Ast) -> (*const Argument, usize)
|
||||
;; define-fn: fn parse_args(ast: *mut Ast) -> (*const u64, usize)
|
||||
parse_args:
|
||||
push rbp
|
||||
mov rbp, rsp
|
||||
push rdi
|
||||
sub rsp, 64
|
||||
; vec: [32..72]
|
||||
; argument: [8..32]
|
||||
; ast [0..8]
|
||||
sub rsp, 72
|
||||
mov [rsp], rdi ; Ast
|
||||
|
||||
lea rdi, [rsp + 24] ; vec
|
||||
mov rsi, 24 ; size of Argument
|
||||
lea rdi, [rsp + 32] ; vec
|
||||
mov rsi, 8 ; size of AstArgument
|
||||
mov rdx, 0 ; drop = None
|
||||
mov rcx, 16 ; capacity
|
||||
call vec_init_with
|
||||
|
|
@ -189,19 +193,39 @@ parse_args:
|
|||
mov dil, TOKEN_RPARENS
|
||||
call expect_token
|
||||
test rax, rax
|
||||
jz .done_args
|
||||
jnz .done_args
|
||||
mov dil, TOKEN_IDENT
|
||||
call unwrap_token
|
||||
mov [rsp], rax ; arg name
|
||||
mov [rsp + 8], rdx ; arg name length
|
||||
mov [rsp + 8], rax ; AstArgument.name
|
||||
mov [rsp + 16], rdx ; AstArgument.name_len
|
||||
mov dil, TOKEN_COLON
|
||||
call unwrap_token
|
||||
mov rdi, [rsp + 64] ; Ast
|
||||
mov rdi, [rsp] ; Ast
|
||||
call parse_type
|
||||
mov [rsp + 16], rax ; arg type
|
||||
mov [rsp + 24], rax ; AstArgument.arg_type
|
||||
|
||||
lea rdi, [rsp + 24] ; vec
|
||||
lea rsi, [rsp] ; arg
|
||||
mov rdi, 24
|
||||
mov rsi, 8
|
||||
call bump_alloc
|
||||
mov rdi, rax
|
||||
lea rsi, [rsp + 8] ; &AstArgument
|
||||
mov rdx, 24
|
||||
call memcpy
|
||||
|
||||
mov qword [rsp + 8], AST_ARG ; AstNode.kind
|
||||
mov [rsp + 16], rdi ; AstNode.data
|
||||
mov qword [rsp + 24], 0 ; AstNode.extra
|
||||
|
||||
mov rdi, [rsp] ; Ast
|
||||
lea rsi, [rsp + 8] ; &AstNode
|
||||
call vec_push
|
||||
mov rdi, [rsp] ; Ast
|
||||
mov rax, [rdi + 8] ; Ast.nodes.len()
|
||||
dec rax
|
||||
|
||||
lea rdi, [rsp + 32] ; vec
|
||||
mov [rsp + 8], rax ; argument
|
||||
lea rsi, [rsp + 8] ; &argument
|
||||
call vec_push
|
||||
|
||||
mov dil, TOKEN_COMMA
|
||||
|
|
@ -213,10 +237,9 @@ parse_args:
|
|||
mov dil, TOKEN_RPARENS
|
||||
call unwrap_token
|
||||
.done_args:
|
||||
mov rax, [rsp + 24] ; args_ptr
|
||||
mov rdx, [rsp + 32] ; args_len
|
||||
add rsp, 64
|
||||
pop rdi
|
||||
mov rax, [rsp + 32] ; args_ptr
|
||||
mov rdx, [rsp + 40] ; args_len
|
||||
add rsp, 72
|
||||
pop rbp
|
||||
ret
|
||||
|
||||
|
|
@ -280,6 +303,14 @@ parse_primary_expr:
|
|||
sub rsp, 32
|
||||
mov [rsp], rdi ; Ast
|
||||
|
||||
; start-structs
|
||||
; struct AstVarRef {
|
||||
; resolved: u64,
|
||||
; name: *const u8,
|
||||
; name_len: usize,
|
||||
; }
|
||||
; end-structs
|
||||
|
||||
mov dil, TOKEN_NUMBER
|
||||
call expect_token
|
||||
test rax, rax
|
||||
|
|
@ -288,7 +319,35 @@ parse_primary_expr:
|
|||
call expect_token
|
||||
test rax, rax
|
||||
jnz .paren_expr
|
||||
mov dil, TOKEN_IDENT
|
||||
call expect_token
|
||||
test rax, rax
|
||||
jnz .var_ref
|
||||
jmp .panic
|
||||
.var_ref:
|
||||
mov qword [rsp + 8], 0 ; AstVarRef.resolved
|
||||
mov [rsp + 16], rax ; AstVarRef.name
|
||||
mov [rsp + 24], rdx ; AstVarRef.name_len
|
||||
|
||||
mov rdi, 24
|
||||
mov rsi, 8
|
||||
call bump_alloc
|
||||
mov rdi, rax
|
||||
lea rsi, [rsp + 8]
|
||||
mov rdx, 24
|
||||
call memcpy
|
||||
|
||||
mov qword [rsp + 8], AST_VAR_REF ; AstNode.kind
|
||||
mov [rsp + 16], rdi ; AstNode.data
|
||||
mov qword [rsp + 24], 0 ; AstNode.extra
|
||||
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, 1 ; placeness = true
|
||||
jmp .epilogue
|
||||
.number:
|
||||
mov rdi, rax ; lexeme ptr
|
||||
mov rsi, rdx ; lexeme len
|
||||
|
|
|
|||
|
|
@ -28,40 +28,71 @@ fn main() {
|
|||
};
|
||||
}
|
||||
|
||||
print_ast(b"3 + 4", |ast| unsafe {
|
||||
parse_expr(ast);
|
||||
});
|
||||
print_ast(b"fn main() -> void { return 1 + 2; }", |ast| unsafe {
|
||||
parse_func(ast);
|
||||
});
|
||||
print_ast(b"fn main() -> void { return (1 + (2)); }", |ast| unsafe {
|
||||
parse_func(ast);
|
||||
});
|
||||
// print_ast(b"3 + 4", |ast| unsafe {
|
||||
// parse_expr(ast);
|
||||
// });
|
||||
// print_ast(b"fn main() -> void { return 1 + 2; }", |ast| unsafe {
|
||||
// parse_func(ast);
|
||||
// });
|
||||
// print_ast(b"fn main() -> void { return (1 + (2)); }", |ast| unsafe {
|
||||
// parse_func(ast);
|
||||
// });
|
||||
// print_ast(
|
||||
// b"fn main() -> void { return (1 + (2 * 3)) / 4; }",
|
||||
// |ast| unsafe {
|
||||
// parse_func(ast);
|
||||
// },
|
||||
// );
|
||||
// print_ast(b"fn main() -> void { return 1 + 2 * 3; }", |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() -> void { return (1 + (2 * 3)) / 4; }",
|
||||
b"fn main(a: u32) -> void { let x: u32 = a + 4; }",
|
||||
|ast| unsafe {
|
||||
parse_func(ast);
|
||||
},
|
||||
);
|
||||
print_ast(b"fn main() -> void { return 1 + 2 * 3; }", |ast| unsafe {
|
||||
parse_func(ast);
|
||||
});
|
||||
|
||||
print_ast(b"fn main() -> void { let x: u32 = 4; }", |ast| unsafe {
|
||||
parse_func(ast);
|
||||
});
|
||||
}
|
||||
|
||||
impl std::fmt::Display for AstNode {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
use util::defs::{
|
||||
BinaryExpr, AST_ADDRESS_OF, AST_ASSIGNMENT, AST_BINARY_OP, AST_BLOCK, AST_DEREF,
|
||||
AST_FUNCTION, AST_NUMBER, AST_RETURN_STATEMENT, AST_VAR_DECL, AST_VAR_REF,
|
||||
BinaryExpr, AST_ADDRESS_OF, AST_ARG, AST_ASSIGNMENT, AST_BINARY_OP, AST_BLOCK,
|
||||
AST_DEREF, AST_FUNCTION, AST_NUMBER, AST_PLACE_TO_VALUE, AST_RETURN_STATEMENT,
|
||||
AST_VALUE_TO_PLACE, AST_VAR_DECL, AST_VAR_REF,
|
||||
};
|
||||
match self.kind as u32 {
|
||||
match self.kind {
|
||||
AST_NUMBER => {
|
||||
write!(f, "Number({})", self.data as usize)
|
||||
}
|
||||
AST_ARG => {
|
||||
let arg = unsafe { self.data.cast::<util::defs::AstArgument>().read() };
|
||||
write!(
|
||||
f,
|
||||
"Arg(name: {:?}, arg_type: {:?})",
|
||||
unsafe {
|
||||
std::str::from_utf8(std::slice::from_raw_parts(arg.name, arg.name_len))
|
||||
},
|
||||
arg.arg_type,
|
||||
)
|
||||
}
|
||||
AST_VAR_REF => {
|
||||
let var_ref = unsafe { self.data.cast::<util::defs::AstVarRef>().read() };
|
||||
if var_ref.resolved != 0 {
|
||||
write!(f, "VarRef({})", var_ref.resolved)
|
||||
} else {
|
||||
write!(f, "VarRef(name: {:?})", unsafe {
|
||||
std::str::from_utf8(std::slice::from_raw_parts(
|
||||
var_ref.name,
|
||||
var_ref.name_len,
|
||||
))
|
||||
},)
|
||||
}
|
||||
}
|
||||
AST_VAR_DECL => {
|
||||
let var_decl = unsafe { self.data.cast::<util::defs::AstVarDecl>().read() };
|
||||
write!(
|
||||
|
|
@ -103,10 +134,13 @@ impl std::fmt::Display for AstNode {
|
|||
let func = unsafe { self.data.cast::<util::defs::AstFunction>().read() };
|
||||
write!(
|
||||
f,
|
||||
"Function(name: {:?}, return_type: {:?}, body: {})",
|
||||
"Function(name: {:?}, args: {:?}, return_type: {:?}, body: {})",
|
||||
unsafe {
|
||||
std::str::from_utf8(std::slice::from_raw_parts(func.name, func.name_len))
|
||||
},
|
||||
unsafe {
|
||||
std::slice::from_raw_parts(func.args.cast::<u64>(), func.args_len as usize)
|
||||
},
|
||||
func.return_type,
|
||||
func.body
|
||||
)
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
unsafe extern "C" {
|
||||
pub unsafe fn parse_func(ast: *mut Ast) -> u64;
|
||||
pub unsafe fn parse_args(ast: *mut Ast) -> (*const Argument, usize);
|
||||
pub unsafe fn parse_args(ast: *mut Ast) -> (*const u64, usize);
|
||||
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_expr(ast: *mut Ast) -> u64;
|
||||
|
|
@ -15,19 +15,20 @@ unsafe extern "C" {
|
|||
pub unsafe fn ast_parse_let(ast: *mut Ast) -> (u64, bool);
|
||||
}
|
||||
|
||||
pub const AST_FUNCTION: u32 = 1;
|
||||
pub const AST_BLOCK: u32 = 2;
|
||||
pub const AST_VARIABLE: u32 = 3;
|
||||
pub const AST_NUMBER: u32 = 4;
|
||||
pub const AST_BINARY_OP: u32 = 5;
|
||||
pub const AST_RETURN_STATEMENT: u32 = 6;
|
||||
pub const AST_VALUE_TO_PLACE: u32 = 7;
|
||||
pub const AST_PLACE_TO_VALUE: u32 = 8;
|
||||
pub const AST_ASSIGNMENT: u32 = 9;
|
||||
pub const AST_DEREF: u32 = 10;
|
||||
pub const AST_ADDRESS_OF: u32 = 11;
|
||||
pub const AST_VAR_DECL: u32 = 12;
|
||||
pub const AST_VAR_REF: u32 = 13;
|
||||
pub const AST_FUNCTION: u8 = 1;
|
||||
pub const AST_BLOCK: u8 = 2;
|
||||
pub const AST_VARIABLE: u8 = 3;
|
||||
pub const AST_NUMBER: u8 = 4;
|
||||
pub const AST_BINARY_OP: u8 = 5;
|
||||
pub const AST_RETURN_STATEMENT: u8 = 6;
|
||||
pub const AST_VALUE_TO_PLACE: u8 = 7;
|
||||
pub const AST_PLACE_TO_VALUE: u8 = 8;
|
||||
pub const AST_ASSIGNMENT: u8 = 9;
|
||||
pub const AST_DEREF: u8 = 10;
|
||||
pub const AST_ADDRESS_OF: u8 = 11;
|
||||
pub const AST_VAR_DECL: u8 = 12;
|
||||
pub const AST_VAR_REF: u8 = 13;
|
||||
pub const AST_ARG: u8 = 14;
|
||||
pub const TYPE_VOID: u32 = 1;
|
||||
pub const TYPE_BOOL: u32 = 2;
|
||||
pub const TYPE_I32: u32 = 3;
|
||||
|
|
@ -97,7 +98,7 @@ pub struct AstNode {
|
|||
|
||||
#[repr(C)]
|
||||
#[derive(Debug)]
|
||||
pub struct Argument {
|
||||
pub struct AstArgument {
|
||||
pub name: *const u8,
|
||||
pub name_len: usize,
|
||||
pub arg_type: Type,
|
||||
|
|
@ -114,12 +115,20 @@ pub struct Type {
|
|||
pub struct AstFunction {
|
||||
pub name: *const u8,
|
||||
pub name_len: usize,
|
||||
pub args: *const Argument,
|
||||
pub args: *const u64,
|
||||
pub args_len: usize,
|
||||
pub return_type: Type,
|
||||
pub body: u64,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Debug)]
|
||||
pub struct AstVarRef {
|
||||
pub resolved: u64,
|
||||
pub name: *const u8,
|
||||
pub name_len: usize,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Debug)]
|
||||
pub struct BinaryExpr {
|
||||
|
|
|
|||
Loading…
Reference in a new issue