github.com/Bytom/bytom@v1.1.2-0.20210127130405-ae40204c0b09/equity/compiler/stack.go (about) 1 package compiler 2 3 type ( 4 stack struct { 5 *stackEntry 6 } 7 stackEntry struct { 8 str string 9 prev *stackEntry 10 } 11 ) 12 13 func (stk stack) isEmpty() bool { 14 return stk.stackEntry == nil 15 } 16 17 func (stk stack) top() string { 18 if stk.isEmpty() { 19 return "" 20 } 21 return stk.str 22 } 23 24 func (stk stack) add(str string) stack { 25 e := &stackEntry{ 26 str: str, 27 prev: stk.stackEntry, 28 } 29 return stack{e} 30 } 31 32 func (stk stack) addFromStack(other stack) stack { 33 if other.isEmpty() { 34 return stk 35 } 36 res := stk.addFromStack(other.drop()) 37 return res.add(other.top()) 38 } 39 40 func (stk stack) drop() stack { 41 if !stk.isEmpty() { 42 stk = stack{stk.prev} 43 } 44 return stk 45 } 46 47 func (stk stack) dropN(n int) stack { 48 for n > 0 { 49 stk = stk.drop() 50 n-- 51 } 52 return stk 53 } 54 55 func (stk stack) recurFind(str string) int { 56 if stk.isEmpty() { 57 return -1 58 } 59 if stk.str == str { 60 return 0 61 } 62 res := stk.drop().recurFind(str) 63 if res < 0 { 64 return res 65 } 66 return res + 1 67 } 68 69 func (stk stack) count() map[string]int { 70 if stk.isEmpty() { 71 return nil 72 } 73 stackCounts := make(map[string]int) 74 for { 75 stackCounts[stk.str]++ 76 stk = stack{stk.prev} 77 if stk.stackEntry == nil { 78 break 79 } 80 } 81 return stackCounts 82 } 83 84 func (stk stack) find(str string) int { 85 stackCounts := stk.count() 86 if stk.isEmpty() || stackCounts[str] == 0 { 87 return -1 88 } 89 90 var pos int 91 for { 92 if stk.str == str { 93 if stackCounts[str] == 1 { 94 break 95 } 96 stackCounts[str]-- 97 } 98 stk = stack{stk.prev} 99 if stk.stackEntry == nil { 100 break 101 } 102 pos++ 103 } 104 return pos 105 } 106 107 func (stk stack) roll(n int) stack { 108 var x func(stack, int) (stack, string) 109 x = func(stk stack, n int) (stack, string) { 110 if n == 0 { 111 return stk.drop(), stk.top() 112 } 113 stk2, entry := x(stk.drop(), n-1) 114 return stk2.add(stk.top()), entry 115 } 116 stk, entry := x(stk, n) 117 return stk.add(entry) 118 } 119 120 func (stk stack) swap() stack { 121 a := stk.top() 122 stk = stk.drop() 123 b := stk.top() 124 stk = stk.drop() 125 return stk.add(a).add(b) 126 } 127 128 func (stk stack) dup() stack { 129 return stk.add(stk.top()) 130 } 131 132 func (stk stack) over() stack { 133 t := stk.drop().top() 134 return stk.add(t) 135 } 136 137 func (stk stack) pick(n int) stack { 138 t := stk.dropN(n).top() 139 return stk.add(t) 140 } 141 142 func (stk stack) String() string { 143 if stk.stackEntry == nil { 144 return "[]" 145 } 146 var x func(stk stack) string 147 x = func(stk stack) string { 148 if stk.stackEntry == nil { 149 return "" 150 } 151 return x(stk.drop()) + " " + stk.stackEntry.str 152 } 153 return "[..." + x(stk) + "]" 154 }