aboutsummaryrefslogtreecommitdiff
path: root/driver.s
diff options
context:
space:
mode:
authorCamil Staps2023-03-05 19:47:49 +0100
committerCamil Staps2023-03-05 19:47:49 +0100
commit4349838a315de8ac9ad51ca2e0fa6f80f24f9241 (patch)
treed030b1fee063cdef58c1e4cf294e3444f167e721 /driver.s
parentRefactor, return MaybeError from lookupFunction and lookupConstructor (diff)
Implement ap
Diffstat (limited to 'driver.s')
-rw-r--r--driver.s51
1 files changed, 49 insertions, 2 deletions
diff --git a/driver.s b/driver.s
index d717270..bd9d901 100644
--- a/driver.s
+++ b/driver.s
@@ -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