https://github.com/akkartik/mu/blob/master/apps/tile/table.mu
 1 fn initialize-table _self: (addr table), n: int {
 2   var self/esi: (addr table) <- copy _self
 3   var data-ah/eax: (addr handle array bind) <- get self, data
 4   populate data-ah, n
 5 }
 6 
 7 fn bind-int-in-table _self: (addr table), key: (addr handle array byte), val: int {
 8   var self/esi: (addr table) <- copy _self
 9   var data-ah/esi: (addr handle array bind) <- get self, data
10   var _data/eax: (addr array bind) <- lookup *data-ah
11   var data/esi: (addr array bind) <- copy _data
12   var next-empty-slot-index/eax: (offset bind) <- next-empty-slot data, key
13   var dest/eax: (addr bind) <- index data, next-empty-slot-index
14   make-binding dest, key, val
15 }
16 
17 # manual test: full array of binds
18 fn next-empty-slot _data: (addr array bind), key: (addr handle array byte) -> result/eax: (offset bind) {
19   var data/esi: (addr array bind) <- copy _data
20   var len/ecx: int <- length data
21   var i/edx: int <- copy 0
22   $next-empty-slot:loop: {
23     result <- compute-offset data, i
24     compare i, len
25     break-if->=
26     {
27       var target/esi: (addr bind) <- index data, result
28       var target2/esi: (addr handle array byte) <- get target, key
29       var target3/eax: (addr array byte) <- lookup *target2
30       compare target3, 0
31       break-if-= $next-empty-slot:loop
32       # TODO: how to indicate that key already exists? we don't want to permit rebinding
33     }
34     i <- increment
35     loop
36   }
37 }
38 
39 fn make-binding _self: (addr bind), key: (addr handle array byte), _val: int {
40   var self/esi: (addr bind) <- copy _self
41   var dest/eax: (addr handle array byte) <- get self, key
42   copy-object key, dest
43   var dest2/eax: (addr handle value) <- get self, value
44   allocate dest2
45   var dest3/eax: (addr value) <- lookup *dest2
46   var dest4/eax: (addr int) <- get dest3, scalar-data
47   var val/ecx: int <- copy _val
48   copy-to *dest4, val
49 }
50 
51 fn lookup-binding _self: (addr table), key: (addr array byte), out: (addr handle value) {
52   var self/esi: (addr table) <- copy _self
53   var data-ah/esi: (addr handle array bind) <- get self, data
54   var _data/eax: (addr array bind) <- lookup *data-ah
55   var data/esi: (addr array bind) <- copy _data
56   var len/edx: int <- length data
57   var i/ebx: int <- copy 0
58   $lookup-binding:loop: {
59     compare i, len
60     break-if->=
61     {
62       var offset/edx: (offset bind) <- compute-offset data, i
63       var target-bind/esi: (addr bind) <- index data, offset
64       var target2/edx: (addr handle array byte) <- get target-bind, key
65       var target3/eax: (addr array byte) <- lookup *target2
66       compare target3, 0
67       break-if-= $lookup-binding:loop
68       var is-match?/eax: boolean <- string-equal? target3, key
69       compare is-match?, 0  # false
70       break-if-=
71       # found
72       var target/eax: (addr handle value) <- get target-bind, value
73       copy-object target, out
74       break $lookup-binding:loop
75     }
76     i <- increment
77     loop
78   }
79 }