diff options
author | Kartik K. Agaram <vc@akkartik.com> | 2015-06-18 11:16:37 -0700 |
---|---|---|
committer | Kartik K. Agaram <vc@akkartik.com> | 2015-06-18 11:16:43 -0700 |
commit | 9e86933229e6d6d45f0192a23e618557540d21d9 (patch) | |
tree | 491e8745b0e7f87f7045da68f00c212459145dcb | |
parent | 28c52ee125769488d790e8524095ca27f0f18795 (diff) | |
download | mu-9e86933229e6d6d45f0192a23e618557540d21d9.tar.gz |
1593
-rw-r--r-- | 030container.cc | 3 | ||||
-rw-r--r-- | 065duplex_list.mu | 75 |
2 files changed, 77 insertions, 1 deletions
diff --git a/030container.cc b/030container.cc index a1bb2290..9f337251 100644 --- a/030container.cc +++ b/030container.cc @@ -107,7 +107,8 @@ case GET: { reagent base = current_instruction().ingredients.at(0); long long int base_address = base.value; type_number base_type = base.types.at(0); - assert(Type[base_type].kind == container); + if (Type[base_type].kind != container) + raise << "'get' on a non-container in " << current_recipe_name () << ": " << current_instruction().to_string() << '\n' << die(); assert(is_literal(current_instruction().ingredients.at(1))); assert(scalar(ingredients.at(1))); long long int offset = ingredients.at(1).at(0); diff --git a/065duplex_list.mu b/065duplex_list.mu index 9caf21d3..8334066c 100644 --- a/065duplex_list.mu +++ b/065duplex_list.mu @@ -210,3 +210,78 @@ scenario inserting-after-start-of-duplex-list [ 10 <- 1 # list back at start ] ] + +# 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. +recipe remove-duplex [ + default-space:address:array:location <- new location:type, 30:literal + in:address:duplex-list <- next-ingredient + # if 'in' is null, return + reply-unless in:address:duplex-list, in:address:duplex-list + next-node:address:duplex-list <- get in:address:duplex-list/deref, next:offset + prev-node:address:duplex-list <- get in:address:duplex-list/deref, prev:offset + # null in's pointers + x:address:address:duplex-list <- get-address in:address:duplex-list/deref, next:offset + x:address:address:duplex-list/deref <- copy 0:literal + x:address:address:duplex-list <- get-address in:address:duplex-list/deref, prev:offset + x:address:address:duplex-list/deref <- copy 0:literal + { + # if next-node is not null + break-unless next-node:address:duplex-list + # next-node.prev = prev-node + x:address:address:duplex-list <- get-address next-node:address:duplex-list/deref, prev:offset + x:address:address:duplex-list/deref <- copy prev-node:address:duplex-list + } + { + # if prev-node is not null + break-unless prev-node:address:duplex-list + # prev-node.next = next-node + x:address:address:duplex-list <- get-address prev-node:address:duplex-list/deref, next:offset + x:address:address:duplex-list/deref <- copy next-node:address:duplex-list + reply prev-node:address:duplex-list + } + reply next-node:address:duplex-list +] + +scenario removing-from-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 + 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 + # check structure like before + 2:address:duplex-list <- copy 1:address:duplex-list + 3:number <- first 2:address:duplex-list + 2:address:duplex-list <- next-duplex 2:address:duplex-list + 4:number <- first 2:address:duplex-list + 5:address:duplex-list <- next-duplex 2:address:duplex-list + 2:address:duplex-list <- prev-duplex 2:address:duplex-list + 6:number <- first 2:address:duplex-list + 7:boolean <- equal 1:address:duplex-list, 2:address:duplex-list + ] + memory-should-contain [ + 3 <- 5 # scanning next, skipping deleted element + 4 <- 3 + 5 <- 0 # no more elements + 6 <- 5 # prev of final element + 7 <- 1 # list back at start + ] +] + +scenario removing-from-singleton-list [ + run [ + 1:address:duplex-list <- copy 0:literal # 1 points to singleton list + 1:address:duplex-list <- push-duplex 3:literal, 1:address:duplex-list + 2:address:duplex-list <- remove-duplex 1:address:duplex-list + 3:address:duplex-list <- get 1:address:duplex-list/deref, next:offset + 4:address:duplex-list <- get 1:address:duplex-list/deref, prev:offset + ] + memory-should-contain [ + 2 <- 0 # list is now empty + 3 <- 0 # removed node is also detached + 4 <- 0 + ] +] |