about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorKartik K. Agaram <vc@akkartik.com>2021-07-16 22:56:07 -0700
committerKartik K. Agaram <vc@akkartik.com>2021-07-16 22:56:07 -0700
commita43bd8598a21bab6c8869796f20fdbc1bdf0cd6d (patch)
tree2a4d72defb781a79f54dbcc2e18159f158a06631
parent4318d7619acd7f7a04f175146400517de28b856b (diff)
downloadmu-a43bd8598a21bab6c8869796f20fdbc1bdf0cd6d.tar.gz
.
-rw-r--r--400.mu2
-rw-r--r--512array.mu100
2 files changed, 101 insertions, 1 deletions
diff --git a/400.mu b/400.mu
index dc655701..ec050342 100644
--- a/400.mu
+++ b/400.mu
@@ -114,6 +114,6 @@ sig copy-array-object src: (addr array _), dest-ah: (addr handle array _)
 sig array-equal? a: (addr array int), b: (addr array int) -> _/eax: boolean
 sig parse-array-of-ints s: (addr array byte), out: (addr handle array int)
 sig parse-array-of-decimal-ints s: (addr array byte), out: (addr handle array int)
-sig check-array-equal a: (addr array int), expected: (addr string), msg: (addr string)
+sig check-array-equal a: (addr array int), expected: (addr array byte), msg: (addr array byte)
 
 sig integer-divide a: int, b: int -> _/eax: int, _/edx: int
diff --git a/512array.mu b/512array.mu
new file mode 100644
index 00000000..19d5485c
--- /dev/null
+++ b/512array.mu
@@ -0,0 +1,100 @@
+# Inserting and deleting in arrays.
+#
+# The primitives here just do the work of making space and compacting.
+
+fn slide-up _a: (addr array int), start: int, end: int, target: int {
+  var a/esi: (addr array int) <- copy _a
+  var src-idx/ecx: int <- copy start
+  var dest-idx/edx: int <- copy target
+  # if start == target, nothing to do
+  {
+    compare src-idx, dest-idx
+    break-if-!=
+    return
+  }
+  # if start < target, abort
+  {
+    compare src-idx, dest-idx
+    break-if->
+    abort "slide-up: target > start; use slide-down instead"
+  }
+  # perform the copy
+  {
+    compare src-idx, end
+    break-if->=
+    var dest/ebx: (addr int) <- index a, dest-idx
+    var src/eax: (addr int) <- index a, src-idx
+    var val/eax: int <- copy *src
+    copy-to *dest, val
+    src-idx <- increment
+    dest-idx <- increment
+    loop
+  }
+}
+
+fn slide-down _a: (addr array int), start: int, end: int, target: int {
+  var a/esi: (addr array int) <- copy _a
+  var src-idx/ecx: int <- copy end
+  src-idx <- decrement
+  var dest-idx/edx: int <- copy target
+  dest-idx <- add end
+  dest-idx <- subtract start
+  dest-idx <- decrement
+  # if start == target, nothing to do
+  {
+    compare src-idx, dest-idx
+    break-if-!=
+    return
+  }
+  # if start > target, abort
+  {
+    compare src-idx, dest-idx
+    break-if-<
+    abort "slide-down: target < start; use slide-down instead"
+  }
+  # perform the copy
+  {
+    compare src-idx, start
+    break-if-<
+    var dest/ebx: (addr int) <- index a, dest-idx
+    var src/eax: (addr int) <- index a, src-idx
+    var val/eax: int <- copy *src
+    copy-to *dest, val
+    src-idx <- decrement
+    dest-idx <- decrement
+    loop
+  }
+}
+
+fn test-slide-up {
+  check-slide-up "0 1 2 3 0", 1/start 1/end, 0/target, "0 1 2 3 0", "F - test-slide-up/empty-interval"
+  check-slide-up "0 1 2 3 0", 1/start 2/end, 0/target, "1 1 2 3 0", "F - test-slide-up/single-non-overlapping"
+  check-slide-up "0 0 0 1 2 3 0", 3/start 6/end, 0/target, "1 2 3 1 2 3 0", "F - test-slide-up/multiple-non-overlapping"
+  check-slide-up "0 1 2 3 0", 1/start 4/end, 0/target, "1 2 3 3 0", "F - test-slide-up/overlapping"
+}
+
+fn test-slide-down {
+  check-slide-down "0 1 2 3 0", 1/start 1/end, 4/target, "0 1 2 3 0", "F - test-slide-down/empty-interval"
+  check-slide-down "0 1 2 3 0", 1/start 2/end, 4/target, "0 1 2 3 1", "F - test-slide-down/single-non-overlapping"
+  check-slide-down "0 1 2 3 0 0 0", 1/start 4/end, 4/target, "0 1 2 3 1 2 3", "F - test-slide-down/multiple-non-overlapping"
+  check-slide-down "0 1 2 3 0", 1/start 4/end, 2/target, "0 1 1 2 3", "F - test-slide-down/overlapping"
+}
+
+# helpers for tests
+fn check-slide-up before: (addr array byte), start: int, end: int, target: int, after: (addr array byte), msg: (addr array byte) {
+  var arr-h: (handle array int)
+  var arr-ah/eax: (addr handle array int) <- address arr-h
+  parse-array-of-decimal-ints before, arr-ah
+  var arr/eax: (addr array int) <- lookup *arr-ah
+  slide-up arr, start, end, target
+  check-array-equal arr, after, msg
+}
+
+fn check-slide-down before: (addr array byte), start: int, end: int, target: int, after: (addr array byte), msg: (addr array byte) {
+  var arr-h: (handle array int)
+  var arr-ah/eax: (addr handle array int) <- address arr-h
+  parse-array-of-decimal-ints before, arr-ah
+  var arr/eax: (addr array int) <- lookup *arr-ah
+  slide-down arr, start, end, target
+  check-array-equal arr, after, msg
+}