diff options
Diffstat (limited to 'driver.s')
-rw-r--r-- | driver.s | 51 |
1 files changed, 49 insertions, 2 deletions
@@ -216,7 +216,7 @@ cycle_error: #.byte 1 # arity # TODO: we cannot use the above because SPIM does not accept .byte in text section .align 2 - .word 0x0001 # strictness, arity + .word 0x01000000 # arity, strictness _nroot: la $a0,cycle_error li $v0,4 # print_string @@ -232,10 +232,57 @@ indir_error: #.byte 1 # arity # TODO: we cannot use the above because SPIM does not accept .byte in text section .align 2 - .word 0x0101 # strictness, arity + .word 0x01010000 # arity, strictness _nindir: # indirections are handled in eval la $a0,indir_error li $v0,4 # print_string syscall break 0 + + #.align 1 + #.byte 0x3 # strictness (incorrect; see documentation) + #.byte 2 # arity + # TODO: we cannot use the above because SPIM does not accept .byte in text section + .align 2 + .word 0x02030000 # arity, strictness +_nap: + # 4($s3) is closure to apply + # 8($s3) is argument + # NB: assumption: the closure has no basic value arguments + lw $t0,4($s3) # t0 -> closure + lw $t1,($t0) # t1 -> closure descriptor + lbu $t2,($t1) # t2 = closure arity + # TODO: check heap space + # Create new closure: copy old closure + addi $t3,$t1,4 # t3 -> next closure descriptor + addi $t5,$gp,0 # t5 -> new closure + sw $t3,($gp) + addi $t6,$t0,4 # closure argument iterator +_nap_copy: + beq $t2,$0,_nap_copy_done + addi $gp,$gp,4 # branch delay slot + lw $t4,($t6) # t4 -> closure argument + addi $t6,$t6,4 + sw $t4,($gp) + j _nap_copy + addi $t2,$t2,-1 # branch delay slot +_nap_copy_done: + # Add new argument + lw $t0,8($s3) # t0 -> new argument + sw $t0,($gp) + addi $gp,$gp,4 + # Check if the closure is saturated + lbu $t2,2($t1) # t2 = number of remaining closure arguments - 1 + bne $t2,$0,_nap_no_eval + # Saturated; create thunk + lw $t3,($t3) # function address + sw $t3,($t5) +_nap_no_eval: + # Create indirection + la $t0,_nindir + sw $t0,($s3) + sw $t5,4($s3) + addi $s3,$t5,0 + j eval + nop |