much love
[mu.git] / 512array.mu
blobb2a0ceb0b82c45722d596329cd08b075f5d97bd1
1 # Inserting and deleting in arrays.
3 # The primitives here just do the work of making space and compacting.
5 fn slide-up _a: (addr array int), start: int, end: int, target: int {
6   var a/esi: (addr array int) <- copy _a
7   var src-idx/ecx: int <- copy start
8   var dest-idx/edx: int <- copy target
9   # if start == target, nothing to do
10   {
11     compare src-idx, dest-idx
12     break-if-!=
13     return
14   }
15   # if start < target, abort
16   {
17     compare src-idx, dest-idx
18     break-if->
19     abort "slide-up: target > start; use slide-down instead"
20   }
21   # perform the copy
22   {
23     compare src-idx, end
24     break-if->=
25     var dest/ebx: (addr int) <- index a, dest-idx
26     var src/eax: (addr int) <- index a, src-idx
27     var val/eax: int <- copy *src
28     copy-to *dest, val
29     src-idx <- increment
30     dest-idx <- increment
31     loop
32   }
35 fn slide-down _a: (addr array int), start: int, end: int, target: int {
36   var a/esi: (addr array int) <- copy _a
37   var src-idx/ecx: int <- copy end
38   src-idx <- decrement
39   var dest-idx/edx: int <- copy target
40   dest-idx <- add end
41   dest-idx <- subtract start
42   dest-idx <- decrement
43   # if start == target, nothing to do
44   {
45     compare src-idx, dest-idx
46     break-if-!=
47     return
48   }
49   # if start > target, abort
50   {
51     compare src-idx, dest-idx
52     break-if-<
53     abort "slide-down: target < start; use slide-down instead"
54   }
55   # perform the copy
56   {
57     compare src-idx, start
58     break-if-<
59     var dest/ebx: (addr int) <- index a, dest-idx
60     var src/eax: (addr int) <- index a, src-idx
61     var val/eax: int <- copy *src
62     copy-to *dest, val
63     src-idx <- decrement
64     dest-idx <- decrement
65     loop
66   }
69 fn test-slide-up {
70   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"
71   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"
72   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"
73   check-slide-up "0 1 2 3 0", 1/start 4/end, 0/target, "1 2 3 3 0", "F - test-slide-up/overlapping"
76 fn test-slide-down {
77   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"
78   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"
79   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"
80   check-slide-down "0 1 2 3 0", 1/start 4/end, 2/target, "0 1 1 2 3", "F - test-slide-down/overlapping"
83 # Return the index that val is at.
84 # If not found, return len-1.
85 # That way the result is always a valid index to pass into slide-down.
86 fn find-slide-down-slot-in-array _a: (addr array int), _val: int -> _/ecx: int {
87   var a/esi: (addr array int) <- copy _a
88   var val/ebx: int <- copy _val
89   var max/edx: int <- length a
90   max <- decrement
91   var i/ecx: int <- copy 0
92   {
93     compare i, max
94     break-if->=
95     var curr/eax: (addr int) <- index a, i
96     compare *curr, val
97     break-if-=
98     i <- increment
99     loop
100   }
101   return i
104 # helpers for tests
105 fn check-slide-up before: (addr array byte), start: int, end: int, target: int, after: (addr array byte), msg: (addr array byte) {
106   var arr-h: (handle array int)
107   var arr-ah/eax: (addr handle array int) <- address arr-h
108   parse-array-of-decimal-ints before, arr-ah
109   var arr/eax: (addr array int) <- lookup *arr-ah
110   slide-up arr, start, end, target
111   check-array-equal arr, after, msg
114 fn check-slide-down before: (addr array byte), start: int, end: int, target: int, after: (addr array byte), msg: (addr array byte) {
115   var arr-h: (handle array int)
116   var arr-ah/eax: (addr handle array int) <- address arr-h
117   parse-array-of-decimal-ints before, arr-ah
118   var arr/eax: (addr array int) <- lookup *arr-ah
119   slide-down arr, start, end, target
120   check-array-equal arr, after, msg