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-in-table _self: (addr table), key: (addr handle array byte), val: (addr value) {
 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) -> _/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   var result/eax: (offset bind) <- copy 0
23   $next-empty-slot:loop: {
24     result <- compute-offset data, i
25     compare i, len
26     break-if->=
27     {
28       var target/esi: (addr bind) <- index data, result
29       var target2/esi: (addr handle array byte) <- get target, key
30       var target3/eax: (addr array byte) <- lookup *target2
31       compare target3, 0
32       break-if-= $next-empty-slot:loop
33       # TODO: how to indicate that key already exists? we don't want to permit rebinding
34     }
35     i <- increment
36     loop
37   }
38   return result
39 }
40 
41 fn make-int-binding _self: (addr bind), key: (addr handle array byte), _val: int {
42   var self/esi: (addr bind) <- copy _self
43   var dest/eax: (addr handle array byte) <- get self, key
44   copy-object key, dest
45   var dest2/eax: (addr handle value) <- get self, value
46   allocate dest2
47   var dest3/eax: (addr value) <- lookup *dest2
48   var dest4/eax: (addr int) <- get dest3, int-data
49   var val/ecx: int <- copy _val
50   copy-to *dest4, val
51 }
52 
53 fn make-binding _self: (addr bind), key: (addr handle array byte), val: (addr value) {
54   var self/esi: (addr bind) <- copy _self
55   var dest/eax: (addr handle array byte) <- get self, key
56   copy-object key, dest
57   var dest2/eax: (addr handle value) <- get self, value
58   allocate dest2
59   var dest3/eax: (addr value) <- lookup *dest2
60   copy-object val, dest3
61 }
62 
63 fn lookup-binding _self: (addr table), key: (addr array byte), out: (addr handle value) {
64   var self/esi: (addr table) <- copy _self
65   var data-ah/esi: (addr handle array bind) <- get self, data
66   var _data/eax: (addr array bind) <- lookup *data-ah
67   var data/esi: (addr array bind) <- copy _data
68   var len/edx: int <- length data
69   var i/ebx: int <- copy 0
70   $lookup-binding:loop: {
71     compare i, len
72     break-if->=
73     {
74       var offset/edx: (offset bind) <- compute-offset data, i
75       var target-bind/esi: (addr bind) <- index data, offset
76       var target2/edx: (addr handle array byte) <- get target-bind, key
77       var target3/eax: (addr array byte) <- lookup *target2
78       compare target3, 0
79       break-if-= $lookup-binding:loop
80       var is-match?/eax: boolean <- string-equal? target3, key
81       compare is-match?, 0  # false
82       break-if-=
83       # found
84       var target/eax: (addr handle value) <- get target-bind, value
85       copy-object target, out
86       break $lookup-binding:loop
87     }
88     i <- increment
89     loop
90   }
91 }