https://github.com/akkartik/mu/blob/main/linux/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 deep-copy-table _src: (addr table), _dest: (addr table) {
      8 #?   print-string 0, "deep-copy-table\n"
      9   var src/eax: (addr table) <- copy _src
     10   var src-data-ah/eax: (addr handle array bind) <- get src, data
     11   var _src-data/eax: (addr array bind) <- lookup *src-data-ah
     12   var src-data/esi: (addr array bind) <- copy _src-data
     13   var n/ecx: int <- length src-data
     14   var dest/eax: (addr table) <- copy _dest
     15   initialize-table dest, n
     16   var dest-data-ah/eax: (addr handle array bind) <- get dest, data
     17   var _dest-data/eax: (addr array bind) <- lookup *dest-data-ah
     18   var dest-data/edi: (addr array bind) <- copy _dest-data
     19   var i/eax: int <- copy 0
     20   {
     21     compare i, n
     22     break-if->=
     23 #?     print-string 0, "iter\n"
     24     $deep-copy:element: {
     25       var offset/edx: (offset bind) <- compute-offset src-data, i
     26       var src-bind/ecx: (addr bind) <- index src-data, offset
     27       var dest-bind/edx: (addr bind) <- index dest-data, offset
     28       var src-key-ah/ebx: (addr handle array byte) <- get src-bind, key
     29       var src-key/eax: (addr array byte) <- lookup *src-key-ah
     30       compare src-key, 0
     31       break-if-=
     32       # copy key
     33       var dest-key-ah/eax: (addr handle array byte) <- get dest-bind, key
     34       copy-object src-key-ah, dest-key-ah
     35       # deep copy value
     36       var src-val-ah/eax: (addr handle value) <- get src-bind, value
     37       var _src-val/eax: (addr value) <- lookup *src-val-ah
     38       var src-val/ecx: (addr value) <- copy _src-val
     39       var dest-val-ah/eax: (addr handle value) <- get dest-bind, value
     40       allocate dest-val-ah
     41       var dest-val/eax: (addr value) <- lookup *dest-val-ah
     42 #?       print-string 0, "deep copy value {\n"
     43       deep-copy-value src-val, dest-val
     44 #?       print-string 0, "}\n"
     45     }
     46     i <- increment
     47     loop
     48   }
     49 #?   print-string 0, "end deep-copy-table\n"
     50 }
     51
     52 fn bind-in-table _self: (addr table), key: (addr handle array byte), val: (addr value) {
     53   var self/esi: (addr table) <- copy _self
     54   var data-ah/esi: (addr handle array bind) <- get self, data
     55   var _data/eax: (addr array bind) <- lookup *data-ah
     56   var data/esi: (addr array bind) <- copy _data
     57   var next-empty-slot-index/eax: (offset bind) <- next-empty-slot data, key
     58   var dest/eax: (addr bind) <- index data, next-empty-slot-index
     59   make-binding dest, key, val
     60 }
     61
     62 # manual test: full array of binds
     63 fn next-empty-slot _data: (addr array bind), key: (addr handle array byte) -> _/eax: (offset bind) {
     64   var data/esi: (addr array bind) <- copy _data
     65   var len/ecx: int <- length data
     66   var i/edx: int <- copy 0
     67   var result/eax: (offset bind) <- copy 0
     68   $next-empty-slot:loop: {
     69     result <- compute-offset data, i
     70     compare i, len
     71     break-if->=
     72     {
     73       var target/esi: (addr bind) <- index data, result
     74       var target2/esi: (addr handle array byte) <- get target, key
     75       var target3/eax: (addr array byte) <- lookup *target2
     76       compare target3, 0
     77       break-if-= $next-empty-slot:loop
     78       # TODO: how to indicate that key already exists? we don't want to permit rebinding
     79     }
     80     i <- increment
     81     loop
     82   }
     83   return result
     84 }
     85
     86 fn make-number-binding _self: (addr bind), key: (addr handle array byte), _val: float {
     87   var self/esi: (addr bind) <- copy _self
     88   var dest/eax: (addr handle array byte) <- get self, key
     89   copy-object key, dest
     90   var dest2/eax: (addr handle value) <- get self, value
     91   allocate dest2
     92   var dest3/eax: (addr value) <- lookup *dest2
     93   var dest4/eax: (addr float) <- get dest3, number-data
     94   var val/xmm0: float <- copy _val
     95   copy-to *dest4, val
     96 }
     97
     98 fn make-binding _self: (addr bind), key: (addr handle array byte), val: (addr value) {
     99   var self/esi: (addr bind) <- copy _self
    100   var dest/eax: (addr handle array byte) <- get self, key
    101   copy-object key, dest
    102   var dest2/eax: (addr handle value) <- get self, value
    103   allocate dest2
    104   var dest3/eax: (addr value) <- lookup *dest2
    105   copy-object val, dest3
    106 }
    107
    108 fn lookup-binding _self: (addr table), key: (addr array byte), out: (addr handle value) {
    109   var self/esi: (addr table) <- copy _self
    110   var data-ah/esi: (addr handle array bind) <- get self, data
    111   var _data/eax: (addr array bind) <- lookup *data-ah
    112   var data/esi: (addr array bind) <- copy _data
    113   var len/edx: int <- length data
    114   var i/ebx: int <- copy 0
    115   $lookup-binding:loop: {
    116     compare i, len
    117     break-if->=
    118     {
    119       var offset/edx: (offset bind) <- compute-offset data, i
    120       var target-bind/esi: (addr bind) <- index data, offset
    121       var target2/edx: (addr handle array byte) <- get target-bind, key
    122       var target3/eax: (addr array byte) <- lookup *target2
    123       compare target3, 0
    124       break-if-= $lookup-binding:loop
    125       var match?/eax: boolean <- string-equal? target3, key
    126       compare match?, 0/false
    127       break-if-=
    128       # found
    129       var target/eax: (addr handle value) <- get target-bind, value
    130       copy-object target, out
    131       break $lookup-binding:loop
    132     }
    133     i <- increment
    134     loop
    135   }
    136 }
    137
    138 fn dump-table _self: (addr table) {
    139   var self/esi: (addr table) <- copy _self
    140   var data-ah/esi: (addr handle array bind) <- get self, data
    141   var _data/eax: (addr array bind) <- lookup *data-ah
    142   var data/esi: (addr array bind) <- copy _data
    143   var len/edx: int <- length data
    144   var i/ebx: int <- copy 0
    145   {
    146     compare i, len
    147     break-if->=
    148     var offset/edx: (offset bind) <- compute-offset data, i
    149     var target-bind/esi: (addr bind) <- index data, offset
    150     var key-ah/edx: (addr handle array byte) <- get target-bind, key
    151     var key/eax: (addr array byte) <- lookup *key-ah
    152     compare key, 0
    153     break-if-=
    154     print-string 0, key
    155     print-string 0, ": "
    156     var val-ah/eax: (addr handle value) <- get target-bind, value
    157     var val/eax: (addr value) <- lookup *val-ah
    158     var type/eax: (addr int) <- get val, type
    159     print-int32-hex 0, *type
    160     print-string 0, "\n"
    161     i <- increment
    162     loop
    163   }
    164   print-string 0, "\n"
    165 }