modularise test with shared rust structs

add expect/unwrap token methods to tokeniser to aid with parsing
This commit is contained in:
janis 2025-10-29 14:00:17 +01:00
parent cd21ecb782
commit 86bbab90c3
Signed by: janis
SSH key fingerprint: SHA256:bB1qbbqmDXZNT0KKD5c2Dfjg53JGhj7B3CFcLIzSqq8
5 changed files with 100 additions and 26 deletions

View file

@ -21,6 +21,8 @@ extern is_whitespace
global tokeniser_init
global tokeniser_print
global find_lexeme
global expect_token
global unwrap_token
;; =============================
;; Tokeniser functions
@ -702,3 +704,42 @@ find_lexeme:
mov qword [rdi], TOKEN_COMMENT
mov [rdi + 16], rax
jmp .epilogue
;; dil: expected token
expect_token:
push rbp
mov rbp, rsp
sub rsp, 0x30
mov [rsp], dil
mov rax, [rel cursor] ; current cursor
mov [rsp + 8], rax
lea rdi, [rsp + 0x10]
call find_lexeme
mov rax, [rsp + 0x10] ; found token
mov dil, [rsp] ; expected token
cmp al, dil
je .matched
mov rdi, [rsp + 8] ; restore cursor
mov [rel cursor], rdi ; restore cursor
xor rax, rax
xor rdx, rdx
jmp .epilogue
.matched:
mov rax, [rsp + 0x18] ; lexeme pointer
mov rdx, [rsp + 0x20] ; lexeme length
.epilogue:
add rsp, 0x30
pop rbp
ret
;; dil: expected token
unwrap_token:
push rbp
mov rbp, rsp
call expect_token
test rax, rax
jz .panic
pop rbp
ret
.panic:
call panic

View file

@ -1,9 +1,7 @@
#![feature(allocator_api, box_as_ptr)]
#[unsafe(no_mangle)]
extern "C" fn panic() -> ! {
panic!("Called panic from external code.");
}
#[path = "shared/shared.rs"]
mod util;
unsafe extern "C" {
unsafe fn bump_init();

View file

@ -1,22 +1,7 @@
#[unsafe(no_mangle)]
extern "C" fn panic() -> ! {
panic!("Called panic from external code.");
}
#[path = "shared/shared.rs"]
mod util;
#[repr(C)]
struct FFISlice {
ptr: *const u8,
len: usize,
}
impl FFISlice {
fn as_slice(&self) -> &[u8] {
unsafe { core::slice::from_raw_parts(self.ptr, self.len) }
}
fn as_str(&self) -> &str {
unsafe { core::str::from_utf8_unchecked(self.as_slice()) }
}
}
use util::FFISlice;
unsafe extern "C" {
unsafe fn int_to_str2(value: isize, buffer: *mut u8, buffer_len: usize, radix: u8) -> FFISlice;

View file

@ -0,0 +1,40 @@
#[unsafe(no_mangle)]
extern "C" fn panic() -> ! {
panic!("Called panic from external code.");
}
#[repr(C)]
#[derive(Debug, PartialEq, Eq)]
pub struct FFISlice {
pub ptr: *const u8,
pub len: usize,
}
#[repr(transparent)]
#[derive(Debug, PartialEq, Eq)]
pub struct MaybeFFISlice {
inner: FFISlice,
}
impl MaybeFFISlice {
pub fn is_none(&self) -> bool {
self.inner.ptr.is_null()
}
pub fn into_option(self) -> Option<FFISlice> {
if self.is_none() {
None
} else {
Some(self.inner)
}
}
}
impl FFISlice {
pub fn as_slice(&self) -> &[u8] {
unsafe { core::slice::from_raw_parts(self.ptr, self.len) }
}
pub fn as_str(&self) -> &str {
unsafe { core::str::from_utf8_unchecked(self.as_slice()) }
}
}

View file

@ -1,7 +1,7 @@
#[unsafe(no_mangle)]
extern "C" fn panic() -> ! {
panic!("Called panic from external code.");
}
#[path = "shared/shared.rs"]
mod util;
use util::*;
#[derive(Debug)]
struct Lexeme(u8, &'static str);
@ -55,6 +55,8 @@ unsafe extern "C" {
unsafe fn skip_whitespace() -> ();
unsafe fn find_lexeme() -> LexemeRaw;
unsafe fn expect_token(token: u8) -> MaybeFFISlice;
unsafe fn unwrap_token(token: u8) -> FFISlice;
static mut LEXEMES: *const u8;
static mut LEXEME_LENS: usize;
@ -171,6 +173,14 @@ fn main() {
]
);
eprint!("Initializing tokeniser.. ");
tokeniser_init(c"tests/tokens/function.l".as_ptr());
eprintln!("ok.");
assert_eq!(expect_token(2).into_option(), None);
assert_eq!(expect_token(4).into_option().unwrap().as_str(), "fn");
assert_eq!(unwrap_token(30).as_str(), "my-function");
eprint!("Initializing tokeniser.. ");
tokeniser_init(c"tests/tokens/comment.l".as_ptr());
eprintln!("ok.");