about summary refs log tree commit diff stats
path: root/065duplex_list.mu
diff options
context:
space:
mode:
authorKartik Agaram <vc@akkartik.com>2018-06-15 22:12:03 -0700
committerKartik Agaram <vc@akkartik.com>2018-06-15 22:12:03 -0700
commit0edd9b9fc60440213e4df926ea511419ee291f1e (patch)
tree84b22f7afdeb9110ad7105c5fc070dacff178502 /065duplex_list.mu
parent3f34ac9369978b396d00a4fd02c9fb06b8eea621 (diff)
downloadmu-0edd9b9fc60440213e4df926ea511419ee291f1e.tar.gz
4257 - abortive attempt at safe fat pointers
I've been working on this slowly over several weeks, but it's too hard
to support 0 as the null value for addresses. I constantly have to add
exceptions for scalar value corresponding to an address type (now
occupying 2 locations). The final straw is the test for 'reload':

  x:num <- reload text

'reload' returns an address. But there's no way to know that for
arbitrary instructions.

New plan: let's put this off for a bit and first create support for
literals. Then use 'null' instead of '0' for addresses everywhere. Then
it'll be easy to just change what 'null' means.
Diffstat (limited to '065duplex_list.mu')
-rw-r--r--065duplex_list.mu53
1 files changed, 52 insertions, 1 deletions
diff --git a/065duplex_list.mu b/065duplex_list.mu
index 037cb923..b299fda7 100644
--- a/065duplex_list.mu
+++ b/065duplex_list.mu
@@ -393,12 +393,17 @@ def remove-between start:&:duplex-list:_elem, end:&:duplex-list:_elem/contained-
   # start->next = end
   *next <- put *next, prev:offset, 0
   *start <- put *start, next:offset, end
-  return-unless end
+  {
+    break-if end
+    stash [spliced:] next
+    return
+  }
   # end->prev->next = 0
   # end->prev = start
   prev:&:duplex-list:_elem <- get *end, prev:offset
   assert prev, [malformed duplex list - 2]
   *prev <- put *prev, next:offset, 0
+  stash [spliced:] next
   *end <- put *end, prev:offset, start
 ]
 
@@ -431,6 +436,9 @@ scenario remove-range [
     12 <- 15
     20 <- 0
   ]
+  trace-should-contain [
+    app: spliced: 16 <-> 17 <-> 18
+  ]
 ]
 
 scenario remove-range-to-final [
@@ -466,6 +474,49 @@ scenario remove-range-to-final [
     12 <- 18
     20 <- 0  # no more elements
   ]
+  trace-should-contain [
+    app: spliced: 15 <-> 16 <-> 17
+  ]
+]
+
+scenario remove-range-to-penultimate [
+  local-scope
+  # construct a duplex list with six elements [13, 14, 15, 16, 17, 18]
+  list:&:duplex-list:num <- push 18, 0
+  list <- push 17, list
+  list <- push 16, list
+  list <- push 15, list
+  list <- push 14, list
+  list <- push 13, list
+  run [
+    # delete 15 and 16
+    # start pointer: to the second element
+    list2:&:duplex-list:num <- next list
+    # end pointer: to the last (sixth) element
+    end:&:duplex-list:num <- next list2
+    end <- next end
+    end <- next end
+    remove-between list2, end
+    # now check the list
+    10:num/raw <- get *list, value:offset
+    list <- next list
+    11:num/raw <- get *list, value:offset
+    list <- next list
+    12:num/raw <- get *list, value:offset
+    list <- next list
+    13:num/raw <- get *list, value:offset
+    20:&:duplex-list:num/raw <- next list
+  ]
+  memory-should-contain [
+    10 <- 13
+    11 <- 14
+    12 <- 17
+    13 <- 18
+    20 <- 0  # no more elements
+  ]
+  trace-should-contain [
+    app: spliced: 15 <-> 16
+  ]
 ]
 
 scenario remove-range-empty [