https://github.com/akkartik/mu/blob/main/linux/tile/value-stack.mu

      1 # support for non-int values is untested
      2
      3 type value-stack {
      4   data: (handle array value)
      5   top: int
      6 }
      7
      8 fn initialize-value-stack _self: (addr value-stack), n: int {
      9   var self/esi: (addr value-stack) <- copy _self
     10   var d/edi: (addr handle array value) <- get self, data
     11   populate d, n
     12   var top/eax: (addr int) <- get self, top
     13   copy-to *top, 0
     14 }
     15
     16 fn clear-value-stack _self: (addr value-stack) {
     17   var self/esi: (addr value-stack) <- copy _self
     18   var top/eax: (addr int) <- get self, top
     19   copy-to *top, 0
     20 }
     21
     22 fn push-number-to-value-stack _self: (addr value-stack), _val: float {
     23   var self/esi: (addr value-stack) <- copy _self
     24   var top-addr/ecx: (addr int) <- get self, top
     25   var data-ah/edx: (addr handle array value) <- get self, data
     26   var data/eax: (addr array value) <- lookup *data-ah
     27   var top/edx: int <- copy *top-addr
     28   var dest-offset/edx: (offset value) <- compute-offset data, top
     29   var dest-addr/edx: (addr value) <- index data, dest-offset
     30   var dest-addr2/eax: (addr float) <- get dest-addr, number-data
     31   var val/xmm0: float <- copy _val
     32 #?   print-float-decimal-approximate 0, val, 3
     33   copy-to *dest-addr2, val
     34   increment *top-addr
     35   var type-addr/eax: (addr int) <- get dest-addr, type
     36   copy-to *type-addr, 0/number
     37 }
     38
     39 fn push-string-to-value-stack _self: (addr value-stack), val: (handle array byte) {
     40   var self/esi: (addr value-stack) <- copy _self
     41   var top-addr/ecx: (addr int) <- get self, top
     42   var data-ah/edx: (addr handle array value) <- get self, data
     43   var data/eax: (addr array value) <- lookup *data-ah
     44   var top/edx: int <- copy *top-addr
     45   var dest-offset/edx: (offset value) <- compute-offset data, top
     46   var dest-addr/edx: (addr value) <- index data, dest-offset
     47   var dest-addr2/eax: (addr handle array byte) <- get dest-addr, text-data
     48   copy-handle val, dest-addr2
     49   var dest-addr3/eax: (addr int) <- get dest-addr, type
     50 #?   print-string 0, "setting type to 1: "
     51 #?   {
     52 #?     var foo/eax: int <- copy dest-addr3
     53 #?     print-int32-hex 0, foo
     54 #?   }
     55 #?   print-string 0, "\n"
     56   copy-to *dest-addr3, 1/string
     57   increment *top-addr
     58 }
     59
     60 fn push-array-to-value-stack _self: (addr value-stack), val: (handle array value) {
     61   var self/esi: (addr value-stack) <- copy _self
     62   var top-addr/ecx: (addr int) <- get self, top
     63   var data-ah/edx: (addr handle array value) <- get self, data
     64   var data/eax: (addr array value) <- lookup *data-ah
     65   var top/edx: int <- copy *top-addr
     66   var dest-offset/edx: (offset value) <- compute-offset data, top
     67   var dest-addr/edx: (addr value) <- index data, dest-offset
     68   var dest-addr2/eax: (addr handle array value) <- get dest-addr, array-data
     69   copy-handle val, dest-addr2
     70   # update type
     71   var dest-addr3/eax: (addr int) <- get dest-addr, type
     72   copy-to *dest-addr3, 2/array
     73   increment *top-addr
     74 }
     75
     76 fn push-value-stack _self: (addr value-stack), val: (addr value) {
     77   var self/esi: (addr value-stack) <- copy _self
     78   var top-addr/ecx: (addr int) <- get self, top
     79   var data-ah/edx: (addr handle array value) <- get self, data
     80   var data/eax: (addr array value) <- lookup *data-ah
     81   var top/edx: int <- copy *top-addr
     82   var dest-offset/edx: (offset value) <- compute-offset data, top
     83   var dest-addr/edx: (addr value) <- index data, dest-offset
     84   copy-object val, dest-addr
     85   increment *top-addr
     86 }
     87
     88 fn pop-number-from-value-stack _self: (addr value-stack) -> _/xmm0: float {
     89   var self/esi: (addr value-stack) <- copy _self
     90   var top-addr/ecx: (addr int) <- get self, top
     91   {
     92     compare *top-addr, 0
     93     break-if->
     94     var minus-one/eax: int <- copy -1
     95     var minus-one-f/xmm0: float <- convert minus-one
     96     return minus-one-f
     97   }
     98   decrement *top-addr
     99   var data-ah/edx: (addr handle array value) <- get self, data
    100   var data/eax: (addr array value) <- lookup *data-ah
    101   var top/edx: int <- copy *top-addr
    102   var dest-offset/edx: (offset value) <- compute-offset data, top
    103   var result-addr/eax: (addr value) <- index data, dest-offset
    104   var result-addr2/eax: (addr float) <- get result-addr, number-data
    105   return *result-addr2
    106 }
    107
    108 fn value-stack-empty? _self: (addr value-stack) -> _/eax: boolean {
    109   var self/esi: (addr value-stack) <- copy _self
    110   var top/eax: (addr int) <- get self, top
    111   compare *top, 0
    112   {
    113     break-if-!=
    114     return 1/true
    115   }
    116   return 0/false
    117 }
    118
    119 fn value-stack-length _self: (addr value-stack) -> _/eax: int {
    120   var self/esi: (addr value-stack) <- copy _self
    121   var top-addr/eax: (addr int) <- get self, top
    122   return *top-addr
    123 }
    124
    125 fn save-lines in-h: (handle array (handle array byte)), _out-ah: (addr handle array value) {
    126   var _in/eax: (addr array (handle array byte)) <- lookup in-h
    127   var in/esi: (addr array (handle array byte)) <- copy _in
    128   var len/ecx: int <- length in
    129   var out-ah/edi: (addr handle array value) <- copy _out-ah
    130   populate out-ah, len
    131   var out/eax: (addr array value) <- lookup *out-ah
    132   # copy in into out
    133   var i/ebx: int <- copy 0
    134   {
    135     compare i, len
    136     break-if->=
    137 #?     print-int32-hex 0, i
    138 #?     print-string 0, "\n"
    139     var src/ecx: (addr handle array byte) <- index in, i
    140     var dest-offset/edx: (offset value) <- compute-offset out, i
    141     var dest-val/edx: (addr value) <- index out, dest-offset
    142     var dest/eax: (addr handle array byte) <- get dest-val, text-data
    143     copy-object src, dest
    144     var type/edx: (addr int) <- get dest-val, type
    145     copy-to *type, 1/string
    146     i <- increment
    147     loop
    148   }
    149 }