From 4e0719f891274534a6659e50bf260a2e175f4ad7 Mon Sep 17 00:00:00 2001 From: janis Date: Sat, 4 Jul 2026 21:40:08 +0200 Subject: [PATCH] tests and can eval complex programs --- stages/lisp0/lisp1.asm | 21 ++++++++---- stages/lisp0/test.rs | 62 ++++++++++++++++++++++++++++++++++++ stages/lisp0/tests/add.l | 1 + stages/lisp0/tests/if.l | 1 + stages/lisp0/tests/let.l | 3 ++ stages/lisp0/tests/letstar.l | 3 ++ stages/lisp0/tests/print.l | 7 ++++ stages/lisp0/tests/string.l | 1 + 8 files changed, 92 insertions(+), 7 deletions(-) create mode 100644 stages/lisp0/tests/add.l create mode 100644 stages/lisp0/tests/if.l create mode 100644 stages/lisp0/tests/let.l create mode 100644 stages/lisp0/tests/letstar.l create mode 100644 stages/lisp0/tests/print.l create mode 100644 stages/lisp0/tests/string.l diff --git a/stages/lisp0/lisp1.asm b/stages/lisp0/lisp1.asm index 3a91038..ac609de 100644 --- a/stages/lisp0/lisp1.asm +++ b/stages/lisp0/lisp1.asm @@ -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 diff --git a/stages/lisp0/test.rs b/stages/lisp0/test.rs index 46cc335..488bc63 100644 --- a/stages/lisp0/test.rs +++ b/stages/lisp0/test.rs @@ -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:?}"); + } + } } diff --git a/stages/lisp0/tests/add.l b/stages/lisp0/tests/add.l new file mode 100644 index 0000000..1a9372c --- /dev/null +++ b/stages/lisp0/tests/add.l @@ -0,0 +1 @@ +(+ 1 2 3) diff --git a/stages/lisp0/tests/if.l b/stages/lisp0/tests/if.l new file mode 100644 index 0000000..08728cb --- /dev/null +++ b/stages/lisp0/tests/if.l @@ -0,0 +1 @@ +(if () 1 2) diff --git a/stages/lisp0/tests/let.l b/stages/lisp0/tests/let.l new file mode 100644 index 0000000..2c0a427 --- /dev/null +++ b/stages/lisp0/tests/let.l @@ -0,0 +1,3 @@ +(let ((x 10) + (y 20)) + (+ x y)) diff --git a/stages/lisp0/tests/letstar.l b/stages/lisp0/tests/letstar.l new file mode 100644 index 0000000..126f776 --- /dev/null +++ b/stages/lisp0/tests/letstar.l @@ -0,0 +1,3 @@ +(let* ((x 10) + (y (+ x 10))) + (+ x y)) diff --git a/stages/lisp0/tests/print.l b/stages/lisp0/tests/print.l new file mode 100644 index 0000000..01df093 --- /dev/null +++ b/stages/lisp0/tests/print.l @@ -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)) diff --git a/stages/lisp0/tests/string.l b/stages/lisp0/tests/string.l new file mode 100644 index 0000000..5eb4640 --- /dev/null +++ b/stages/lisp0/tests/string.l @@ -0,0 +1 @@ +("hello, World!" \a \b \NL \Space)