tests and can eval complex programs

This commit is contained in:
janis 2026-07-04 21:40:08 +02:00
parent 52950c255a
commit 4e0719f891
Signed by: janis
SSH key fingerprint: SHA256:bB1qbbqmDXZNT0KKD5c2Dfjg53JGhj7B3CFcLIzSqq8
8 changed files with 92 additions and 7 deletions

View file

@ -500,7 +500,7 @@ next_token:
movzx ecx, al
sub cl, `'`
cmp cl, `)` - `'`
jg .eat
ja .eat
; one of '()
call getc
lea rdi, [rel buf]
@ -560,7 +560,10 @@ next_token:
cmp al, '"'
sete cl
test cl, byte [rsp] ; if getc() == '"' && string_flag, we are done
and cl, byte [rsp] ; getc() == '"' & string_flag, we are done
cmp r14, 2
setae al
test al, cl ; if string_flag && getc() == '"' && !first_char, we are done
jnz .done
call peekc
@ -785,9 +788,9 @@ parse_string:
mov edi, eax
mov esi, 8
call heap_alloc
mov rsi, rax
lea rdi, [rel buf]
inc rdi
mov edi, eax
mov edx, dword [rsp]
push rax
call memcpy
@ -1045,7 +1048,7 @@ make_arr:
push rdx
push rsi
push rdi
mov edi, 16
mov edi, 24
mov esi, 8
call heap_alloc
pop rdi
@ -1126,6 +1129,9 @@ num_is_inline:
ret
num_val:
call obj_tag_part
cmp al, OBJ_NUM
jne panic_abort
call num_is_inline
je .inline
call obj_ptr_part
@ -2511,7 +2517,7 @@ p_car:
mov rdi, qword [rsp]
mov qword [rsp], rax
call obj_dec_ref
mov qword [rsp], rax
mov rax, qword [rsp]
add rsp, 8
ret
@ -2524,7 +2530,7 @@ p_cdr:
mov rdi, qword [rsp]
mov qword [rsp], rax
call obj_dec_ref
mov qword [rsp], rax
mov rax, qword [rsp]
add rsp, 8
ret
@ -3026,8 +3032,9 @@ p_syscall:
jnz ._next_arg_done
call car_cdr
mov rdi, rax ; arg
mov rcx, rdx ; rest
call num_val
mov rdi, rdx ; rest
mov rdi, rcx ; rest
mov rcx, rax ; arg value
mov al, 0
test al, al

View file

@ -312,6 +312,16 @@ mod tests {
}
}
#[test]
fn parse_string() {
let file = ManuallyDrop::new(File::open("tests/string.l").unwrap());
unsafe {
init_source(&raw mut IFILE, file.as_raw_fd());
let obj = parse_next_token();
println!("{:?}", obj);
}
}
#[test]
fn parse_atom() {
let file = ManuallyDrop::new(File::open("tests/atom.l").unwrap());
@ -365,4 +375,56 @@ mod tests {
eprintln!("{result:?}");
}
}
#[test]
fn eval_let() {
let file = ManuallyDrop::new(File::open("tests/let.l").unwrap());
unsafe {
init_source(&raw mut IFILE, file.as_raw_fd());
let expr = parse_next_token();
let env = unsafe { *ENV_INIT };
let result = eval(expr, env);
eprint!("done: ");
eprintln!("{result:?}");
}
}
#[test]
fn eval_letstar() {
let file = ManuallyDrop::new(File::open("tests/letstar.l").unwrap());
unsafe {
init_source(&raw mut IFILE, file.as_raw_fd());
let expr = parse_next_token();
let env = unsafe { *ENV_INIT };
let result = eval(expr, env);
eprint!("done: ");
eprintln!("{result:?}");
}
}
#[test]
fn eval_print() {
let file = ManuallyDrop::new(File::open("tests/print.l").unwrap());
unsafe {
init_source(&raw mut IFILE, file.as_raw_fd());
let expr = parse_next_token();
let env = unsafe { *ENV_INIT };
let result = eval(expr, env);
eprint!("done: ");
eprintln!("{result:?}");
}
}
#[test]
fn eval_if() {
let file = ManuallyDrop::new(File::open("tests/if.l").unwrap());
unsafe {
init_source(&raw mut IFILE, file.as_raw_fd());
let expr = parse_next_token();
let env = unsafe { *ENV_INIT };
let result = eval(expr, env);
eprint!("done: ");
eprintln!("{result:?}");
}
}
}

1
stages/lisp0/tests/add.l Normal file
View file

@ -0,0 +1 @@
(+ 1 2 3)

1
stages/lisp0/tests/if.l Normal file
View file

@ -0,0 +1 @@
(if () 1 2)

3
stages/lisp0/tests/let.l Normal file
View file

@ -0,0 +1,3 @@
(let ((x 10)
(y 20))
(+ x y))

View file

@ -0,0 +1,3 @@
(let* ((x 10)
(y (+ x 10)))
(+ x y))

View file

@ -0,0 +1,7 @@
(let*
((msg "Hello, World!\n")
(msg-parts (str-parts msg))
(ptr (car msg-parts))
(len (cdr msg-parts))
(fd 1))
(syscall 1 fd ptr len))

View file

@ -0,0 +1 @@
("hello, World!" \a \b \NL \Space)