Compare commits

..

10 commits

Author SHA1 Message Date
janis 4f5579b6fd
lints 2025-11-03 17:06:00 +01:00
janis 3526f9d59d
fix stack var logic error 2025-11-03 17:04:11 +01:00
janis 07eeed7cff
can do very cool stuff! 2025-11-03 16:35:46 +01:00
janis 52cfc7dc54
yippie? 2025-11-03 15:16:18 +01:00
janis 8508018b0a
sete doesn't work like that! 2025-11-03 01:02:36 +01:00
janis 8e1af956b0
it doesn't crash (crazy) 2025-11-03 00:54:34 +01:00
janis a93f7edd62
deref needs a value 2025-11-02 18:12:29 +01:00
janis f5188053e7
operands and placeness are hard 2025-11-02 17:49:27 +01:00
janis d46837903b
dangerous: resize width field on Operand 2025-11-02 17:27:30 +01:00
janis 6dff42cfa5
var decl/ varref codegen 2025-11-02 16:49:46 +01:00
8 changed files with 668 additions and 262 deletions

View file

@ -193,6 +193,7 @@ parse_args:
mov rdx, 0 ; drop = None
mov rcx, 16 ; capacity
call vec_init_with
nop
.loop:
mov dil, TOKEN_RPARENS
@ -554,8 +555,11 @@ parse_statement:
jnz .let
mov dil, TOKEN_LBRACE
call peek_expect_token ; parse_block expects lbrace to still be there
test rax, rax
jnz .block
jmp .panic
mov rdi, [rsp] ; Ast
call parse_expr
jmp .epilogue
.block:
mov rdi, [rsp] ; Ast
@ -750,6 +754,11 @@ parse_prefix_expr:
mov rdi, [rsp] ; Ast
call parse_prefix_expr
mov rdi, [rsp] ; Ast
mov rsi, rax ; expr
; mov rdx, rdx ; placeness
call ast_place_to_value
mov qword [rsp + 8], AST_DEREF ; AstNode.kind
mov [rsp + 16], rax ; AstNode.data
mov qword [rsp + 24], 0 ; AstNode.extra

File diff suppressed because it is too large Load diff

View file

@ -12,7 +12,7 @@ unsafe extern "C" {
unsafe fn tokeniser_init_buf(bytes: *const u8, len: usize) -> ();
}
use util::defs::{parse_expr, parse_func, Ast, AstNode};
use util::defs::{parse_func, Ast};
fn main() {
unsafe {
@ -20,8 +20,6 @@ fn main() {
}
println!("Bump allocator initialized.");
let src = b"3 + 4";
fn print_ast(src: &[u8], parser: impl FnOnce(&mut Ast) -> u64) {
unsafe {
tokeniser_init_buf(src.as_ptr(), src.len());
@ -60,50 +58,57 @@ fn main() {
};
}
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 * 4; }",
// |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"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 { let x: u32 = 4; }", |ast| unsafe {
// parse_func(ast)
// });
// print_ast(
// b"fn main(a: u32) -> void { let x: u32 = a + 4; }",
// |ast| unsafe { parse_func(ast) },
// );
// print_ast(
// b"fn main(a: u32) -> void {
// let y: u32 = a + 4;
// let y: *u32 = &y;
// return *y;
// }",
// |ast| unsafe { parse_func(ast) },
// );
// print_ast(
// b"fn main(a: u32) -> void {
// let y: u32 = a + 4;
// {
// let y: u32 = 10;
// }
// let y: *u32 = &y;
// return *y;
// }",
// |ast| unsafe { parse_func(ast) },
// );
print_ast(
b"fn main(a: u32) -> void { let x: u32 = a + 4; }",
|ast| unsafe { parse_func(ast) },
);
print_ast(
b"fn main(a: u32) -> void {
let y: u32 = a + 4;
let y: *u32 = &y;
return *y;
}",
|ast| unsafe { parse_func(ast) },
);
print_ast(
b"fn main(a: u32) -> void {
let y: u32 = a + 4;
{
let y: u32 = 10;
}
let y: *u32 = &y;
return *y;
b"fn main(a: *u32, b: u32) -> void {
*a = b;
a = &b;
}",
|ast| unsafe { parse_func(ast) },
);

View file

@ -56,6 +56,7 @@ fn main() {
#[repr(align(256))]
struct AlignedType {
#[allow(dead_code)]
data: [u8; 512],
}
let aligned = Box::new_in(AlignedType { data: [0; 512] }, BumpAllocator);

View file

@ -6,7 +6,7 @@ mod util;
#[path = "shared/ast_debug.rs"]
mod ast_debug;
use util::defs::{parse_func, Ast, AstNode};
use util::defs::{parse_func, Ast};
unsafe extern "C" {
unsafe fn bump_init();
@ -93,7 +93,8 @@ fn main() {
print_ast(
b"fn main(a: u32) -> void {
return 2 * 3 + 4 * 5;
let b: *u32 = &a;
return 5 + *b;
}",
|ast| unsafe { parse_func(ast) },
);

View file

@ -21,6 +21,7 @@ unsafe extern "C" {
pub unsafe fn stackvar_cmp(a: *const (u64, u64), b: *const (u64, u64)) -> i32;
pub unsafe fn codegen_allocate_register(ctx: *mut FunctionCtx) -> u8;
pub unsafe fn codegen_allocate_place(ctx: *mut FunctionCtx, width: u16) -> Operand;
pub unsafe fn codegen_allocate_stack_value(ctx: *mut FunctionCtx, width: u16) -> Operand;
pub unsafe fn codegen_allocate_value(ctx: *mut FunctionCtx, width: u16) -> Operand;
pub unsafe fn codegen_free_operand(ctx: *mut FunctionCtx, operand: *const Operand) -> ();
pub unsafe fn codegen_function(ast: *const CodegenCtx, func_idx: u64) -> ();
@ -58,12 +59,18 @@ pub const TYPE_U32: u8 = 4;
pub const TYPE_STR: u8 = 5;
pub const TYPE_POINTER: u8 = 6;
pub const OPERAND_REGISTER: u32 = 1;
pub const OPERAND_RBP_OFFSET: u32 = 2;
pub const OPERAND_RSP_OFFSET: u32 = 3;
pub const OPERAND_ADDRESS: u32 = 4;
pub const OPERAND_IMMEDIATE: u32 = 5;
pub const OPERAND_CONSTANT: u32 = 6;
pub const OPERAND_LABEL: u32 = 7;
pub const OPERAND_RBP_VALUE: u32 = 2;
pub const OPERAND_RBP_PVALUE: u32 = 3;
pub const OPERAND_ADDRESS_VALUE: u32 = 4;
pub const OPERAND_LAST_VALUE: u32 = 5;
pub const OPERAND_RBP_OFFSET: u32 = 6;
pub const OPERAND_ADDRESS_PLACE: u32 = 7;
pub const OPERAND_REGISTER_PLACE: u32 = 8;
pub const OPERAND_RBP_PLACE: u32 = 9;
pub const OPERAND_LAST_PLACE: u32 = 10;
pub const OPERAND_IMMEDIATE: u32 = 11;
pub const OPERAND_CONSTANT: u32 = 12;
pub const OPERAND_LABEL: u32 = 13;
pub const TOKEN_EOF: u8 = 0;
pub const TOKEN_LET: u8 = 1;
pub const TOKEN_IF: u8 = 2;
@ -247,7 +254,8 @@ pub struct FunctionCtx {
#[derive(Debug)]
pub struct Operand {
pub kind: u8,
pub register_and_width: u8,
pub register: u8,
pub width: u16,
pub len: u16,
pub value: u64,
}

View file

@ -278,7 +278,7 @@ pub mod vec {
}
}
pub fn insert_sorted<F>(&self, elem: T, mut cmp: F) -> Result<usize, usize>
pub fn insert_sorted<F>(&mut self, elem: T, mut cmp: F) -> Result<usize, usize>
where
F: FnMut(&T, &T) -> i32,
{

View file

@ -118,4 +118,18 @@ fn main() {
let elements = Box::new([6, 7, 8]);
vec.insert_many(2, elements);
assert_eq!(vec.as_slice(), &[50, 1, 6, 7, 8, 2, 3, 4, 5]);
let mut vec = Vec::<u32>::new_with(100);
assert_eq!(vec.len(), 0);
_ = vec.insert_sorted(5, cmp);
assert_eq!(vec.len(), 1);
assert_eq!(vec.as_slice(), &[5]);
_ = vec.insert_sorted(2, cmp);
assert_eq!(vec.len(), 2);
assert_eq!(vec.as_slice(), &[2, 5]);
_ = vec.insert_sorted(7, cmp);
assert_eq!(vec.len(), 3);
assert_eq!(vec.as_slice(), &[2, 5, 7]);
}