diff options
author | Kartik K. Agaram <vc@akkartik.com> | 2015-06-18 11:26:04 -0700 |
---|---|---|
committer | Kartik K. Agaram <vc@akkartik.com> | 2015-06-18 11:37:21 -0700 |
commit | 0ab01e6f00fad00bb2103113c9c90f6c3a042321 (patch) | |
tree | 7701c48a4f6c395506197fe87849cbeef71463fa | |
parent | 9e86933229e6d6d45f0192a23e618557540d21d9 (diff) | |
download | mu-0ab01e6f00fad00bb2103113c9c90f6c3a042321.tar.gz |
1594 - removing from start/end of duplex list
This uncovers an issue with this interface to duplex lists: the caller needs to check the result and invalidate any other pointers if it's null (i.e. the list is now empty) We *could* try to encapsulate the list in a header to help the caller manage header pointers. But heck, let's see if writing tests helps call-sites stay on the straight and narrow.
-rw-r--r-- | 065duplex_list.mu | 71 |
1 files changed, 67 insertions, 4 deletions
diff --git a/065duplex_list.mu b/065duplex_list.mu index 8334066c..287e460b 100644 --- a/065duplex_list.mu +++ b/065duplex_list.mu @@ -213,7 +213,10 @@ scenario inserting-after-start-of-duplex-list [ # l:address:duplex-list <- remove-duplex in:address:duplex-list # Removes 'in' from its surrounding list. Returns some valid pointer into the -# rest of the list. Returns null if and only if list is empty. +# rest of the list. +# +# Returns null if and only if list is empty. Beware: in that case any pointers +# to the head are now invalid. recipe remove-duplex [ default-space:address:array:location <- new location:type, 30:literal in:address:duplex-list <- next-ingredient @@ -252,6 +255,35 @@ scenario removing-from-duplex-list [ 1:address:duplex-list <- push-duplex 5:literal, 1:address:duplex-list 2:address:duplex-list <- next-duplex 1:address:duplex-list # 2 points at second element 2:address:duplex-list <- remove-duplex 2:address:duplex-list + 3:boolean <- equal 2:address:duplex-list, 0:literal + # check structure like before + 2:address:duplex-list <- copy 1:address:duplex-list + 4:number <- first 2:address:duplex-list + 2:address:duplex-list <- next-duplex 2:address:duplex-list + 5:number <- first 2:address:duplex-list + 6:address:duplex-list <- next-duplex 2:address:duplex-list + 2:address:duplex-list <- prev-duplex 2:address:duplex-list + 7:number <- first 2:address:duplex-list + 8:boolean <- equal 1:address:duplex-list, 2:address:duplex-list + ] + memory-should-contain [ + 3 <- 0 # remove returned non-null + 4 <- 5 # scanning next, skipping deleted element + 5 <- 3 + 6 <- 0 # no more elements + 7 <- 5 # prev of final element + 8 <- 1 # list back at start + ] +] + +scenario removing-from-start-of-duplex-list [ + run [ + 1:address:duplex-list <- copy 0:literal # 1 points to head of list + 1:address:duplex-list <- push-duplex 3:literal, 1:address:duplex-list + 1:address:duplex-list <- push-duplex 4:literal, 1:address:duplex-list + 1:address:duplex-list <- push-duplex 5:literal, 1:address:duplex-list + # removing from head? return value matters. + 1:address:duplex-list <- remove-duplex 1:address:duplex-list # check structure like before 2:address:duplex-list <- copy 1:address:duplex-list 3:number <- first 2:address:duplex-list @@ -263,14 +295,45 @@ scenario removing-from-duplex-list [ 7:boolean <- equal 1:address:duplex-list, 2:address:duplex-list ] memory-should-contain [ - 3 <- 5 # scanning next, skipping deleted element + 3 <- 4 # scanning next, skipping deleted element 4 <- 3 5 <- 0 # no more elements - 6 <- 5 # prev of final element + 6 <- 4 # prev of final element 7 <- 1 # list back at start ] ] +scenario removing-from-end-of-duplex-list [ + run [ + 1:address:duplex-list <- copy 0:literal # 1 points to head of list + 1:address:duplex-list <- push-duplex 3:literal, 1:address:duplex-list + 1:address:duplex-list <- push-duplex 4:literal, 1:address:duplex-list + 1:address:duplex-list <- push-duplex 5:literal, 1:address:duplex-list + # delete last element + 2:address:duplex-list <- next-duplex 1:address:duplex-list + 2:address:duplex-list <- next-duplex 2:address:duplex-list + 2:address:duplex-list <- remove-duplex 2:address:duplex-list + 3:boolean <- equal 2:address:duplex-list, 0:literal + # check structure like before + 2:address:duplex-list <- copy 1:address:duplex-list + 4:number <- first 2:address:duplex-list + 2:address:duplex-list <- next-duplex 2:address:duplex-list + 5:number <- first 2:address:duplex-list + 6:address:duplex-list <- next-duplex 2:address:duplex-list + 2:address:duplex-list <- prev-duplex 2:address:duplex-list + 7:number <- first 2:address:duplex-list + 8:boolean <- equal 1:address:duplex-list, 2:address:duplex-list + ] + memory-should-contain [ + 3 <- 0 # remove returned non-null + 4 <- 5 # scanning next, skipping deleted element + 5 <- 4 + 6 <- 0 # no more elements + 7 <- 5 # prev of final element + 8 <- 1 # list back at start + ] +] + scenario removing-from-singleton-list [ run [ 1:address:duplex-list <- copy 0:literal # 1 points to singleton list @@ -280,7 +343,7 @@ scenario removing-from-singleton-list [ 4:address:duplex-list <- get 1:address:duplex-list/deref, prev:offset ] memory-should-contain [ - 2 <- 0 # list is now empty + 2 <- 0 # remove returned null 3 <- 0 # removed node is also detached 4 <- 0 ] |