https://github.com/akkartik/mu/blob/master/apps/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-int-to-value-stack _self: (addr value-stack), _val: int {
 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 int) <- get dest-addr, scalar-data
 31   var val/esi: int <- copy _val
 32 #?   print-int32-hex-to-real-screen val
 33   copy-to *dest-addr2, val
 34   increment *top-addr
 35 }
 36 
 37 fn push-value-stack _self: (addr value-stack), val: (addr value) {
 38   var self/esi: (addr value-stack) <- copy _self
 39   var top-addr/ecx: (addr int) <- get self, top
 40   var data-ah/edx: (addr handle array value) <- get self, data
 41   var data/eax: (addr array value) <- lookup *data-ah
 42   var top/edx: int <- copy *top-addr
 43   var dest-offset/edx: (offset value) <- compute-offset data, top
 44   var dest-addr/edx: (addr value) <- index data, dest-offset
 45   copy-object val, dest-addr
 46   increment *top-addr
 47 }
 48 
 49 fn pop-int-from-value-stack _self: (addr value-stack) -> val/eax: int {
 50 $pop-int-from-value-stack:body: {
 51   var self/esi: (addr value-stack) <- copy _self
 52   var top-addr/ecx: (addr int) <- get self, top
 53   {
 54     compare *top-addr, 0
 55     break-if->
 56     val <- copy -1
 57     break $pop-int-from-value-stack:body
 58   }
 59   decrement *top-addr
 60   var data-ah/edx: (addr handle array value) <- get self, data
 61   var data/eax: (addr array value) <- lookup *data-ah
 62   var top/edx: int <- copy *top-addr
 63   var dest-offset/edx: (offset value) <- compute-offset data, top
 64   var result-addr/eax: (addr value) <- index data, dest-offset
 65   var result-addr2/eax: (addr int) <- get result-addr, scalar-data
 66   val <- copy *result-addr2
 67 }
 68 }
 69 
 70 fn value-stack-empty? _self: (addr value-stack) -> result/eax: boolean {
 71 $value-stack-empty?:body: {
 72   var self/esi: (addr value-stack) <- copy _self
 73   var top/eax: (addr int) <- get self, top
 74   compare *top, 0
 75   {
 76     break-if-!=
 77     result <- copy 1  # true
 78     break $value-stack-empty?:body
 79   }
 80   result <- copy 0  # false
 81 }
 82 }
 83 
 84 fn value-stack-length _self: (addr value-stack) -> result/eax: int {
 85   var self/esi: (addr value-stack) <- copy _self
 86   var top-addr/eax: (addr int) <- get self, top
 87   result <- copy *top-addr
 88 }
 89 
 90 fn value-stack-max-width _self: (addr value-stack) -> result/eax: int {
 91   var self/esi: (addr value-stack) <- copy _self
 92   var data-ah/edi: (addr handle array value) <- get self, data
 93   var _data/eax: (addr array value) <- lookup *data-ah
 94   var data/edi: (addr array value) <- copy _data
 95   var top-addr/ecx: (addr int) <- get self, top
 96   var i/ebx: int <- copy 0
 97   result <- copy 0
 98   {
 99     compare i, *top-addr
100     break-if->=
101     var o/edx: (offset value) <- compute-offset data, i
102     var g/edx: (addr value) <- index data, o
103     var g2/edx: (addr int) <- get g, scalar-data
104     var w/ecx: int <- int-width-decimal *g2
105     compare w, result
106     {
107       break-if-<=
108       result <- copy w
109     }
110     i <- increment
111     loop
112   }
113 }