diff --git a/stages/lisp0/lisp.asm b/stages/lisp0/lisp.asm index b8a0b72..d3f0302 100644 --- a/stages/lisp0/lisp.asm +++ b/stages/lisp0/lisp.asm @@ -117,30 +117,40 @@ extern dealloc PLUS_STR db "+" PLUS_STR_LEN equ $ - PLUS_STR - ;; add $rdi and $rsi + ;; sum list $rdi in env $rsi p_add: + sub rsp, 24 + call eval_list + mov qword [rsp], rax ; evaled list + mov qword [rsp + 8], rsi ; env + mov qword [rsp + 16], 0 ; acc = 0 +.add_loop: + mov rdi, qword [rsp] ; $rdi = evaled list + call get_cdr + mov qword [rsp], rax ; update list to cdr + call get_car + mov rdi, rax ; $rdi = car call obj_tag_part cmp al, OBJ_NUM jne .invalid call obj_addr_part - mov rdx, qword [rax + 8] ; num1 - mov rdi, rsi - call obj_tag_part - cmp al, OBJ_NUM - jne .invalid - call obj_addr_part - mov rax, qword [rax + 8] ; num2 - add rax, rdx ; num1 + num2 - push rax - mov rdi, 16 ; struct { refcount: usize, value: i64 } + mov rax, qword [rax + 8] ; num + add qword [rsp + 16], rax ; acc += num + mov rdi, qword [rsp] ; $rdi = list + lea rsi, [rel nil] + cmp rdi, rsi + jne .add_loop +.done: + mov rdi, 16 mov rsi, 8 call alloc - mov [rax], 1 ; refcount = 1 - pop rdx - mov qword [rax + 8], rdx ; value = sum mov rdi, rax + mov dword [rdi], 1 ; refcount = 1 + mov rax, qword [rsp + 16] ; acc + mov qword [rdi + 8], rax ; value = acc mov rsi, OBJ_NUM call obj_set_tag + add rsp, 24 ret .invalid: xor rdi, rdi @@ -863,6 +873,8 @@ apply: .apply_prim: call obj_addr_part mov rax, qword [rax + 8] ; get the function pointer + mov rdi, rsi ; $rdi = argument list + mov rsi, rdx ; $rsi = environment jmp rax .invalid_func: xor rdi, rdi