+++ /dev/null
-package compiler
-
-type (
- stack struct {
- *stackEntry
- }
- stackEntry struct {
- str string
- prev *stackEntry
- }
-)
-
-func (stk stack) isEmpty() bool {
- return stk.stackEntry == nil
-}
-
-func (stk stack) top() string {
- if stk.isEmpty() {
- return ""
- }
- return stk.str
-}
-
-func (stk stack) add(str string) stack {
- e := &stackEntry{
- str: str,
- prev: stk.stackEntry,
- }
- return stack{e}
-}
-
-func (stk stack) addFromStack(other stack) stack {
- if other.isEmpty() {
- return stk
- }
- res := stk.addFromStack(other.drop())
- return res.add(other.top())
-}
-
-func (stk stack) drop() stack {
- if !stk.isEmpty() {
- stk = stack{stk.prev}
- }
- return stk
-}
-
-func (stk stack) dropN(n int) stack {
- for n > 0 {
- stk = stk.drop()
- n--
- }
- return stk
-}
-
-func (stk stack) recurFind(str string) int {
- if stk.isEmpty() {
- return -1
- }
- if stk.str == str {
- return 0
- }
- res := stk.drop().recurFind(str)
- if res < 0 {
- return res
- }
- return res + 1
-}
-
-func (stk stack) count() map[string]int {
- if stk.isEmpty() {
- return nil
- }
- stackCounts := make(map[string]int)
- for {
- stackCounts[stk.str]++
- stk = stack{stk.prev}
- if stk.stackEntry == nil {
- break
- }
- }
- return stackCounts
-}
-
-func (stk stack) find(str string) int {
- stackCounts := stk.count()
- if stk.isEmpty() || stackCounts[str] == 0 {
- return -1
- }
-
- var pos int
- for {
- if stk.str == str {
- if stackCounts[str] == 1 {
- break
- }
- stackCounts[str]--
- }
- stk = stack{stk.prev}
- if stk.stackEntry == nil {
- break
- }
- pos++
- }
- return pos
-}
-
-func (stk stack) roll(n int) stack {
- var x func(stack, int) (stack, string)
- x = func(stk stack, n int) (stack, string) {
- if n == 0 {
- return stk.drop(), stk.top()
- }
- stk2, entry := x(stk.drop(), n-1)
- return stk2.add(stk.top()), entry
- }
- stk, entry := x(stk, n)
- return stk.add(entry)
-}
-
-func (stk stack) swap() stack {
- a := stk.top()
- stk = stk.drop()
- b := stk.top()
- stk = stk.drop()
- return stk.add(a).add(b)
-}
-
-func (stk stack) dup() stack {
- return stk.add(stk.top())
-}
-
-func (stk stack) over() stack {
- t := stk.drop().top()
- return stk.add(t)
-}
-
-func (stk stack) pick(n int) stack {
- t := stk.dropN(n).top()
- return stk.add(t)
-}
-
-func (stk stack) String() string {
- if stk.stackEntry == nil {
- return "[]"
- }
- var x func(stk stack) string
- x = func(stk stack) string {
- if stk.stackEntry == nil {
- return ""
- }
- return x(stk.drop()) + " " + stk.stackEntry.str
- }
- return "[..." + x(stk) + "]"
-}