github.com/vugu/vugu@v0.3.5/vugufmt/tokenstack.go (about) 1 package vugufmt 2 3 import ( 4 "github.com/vugu/vugu/internal/htmlx" 5 ) 6 7 // tokenStack is a stack of nodes. 8 type tokenStack []*htmlx.Token 9 10 // pop pops the stack. It will panic if s is empty. 11 func (s *tokenStack) pop() *htmlx.Token { 12 i := len(*s) 13 n := (*s)[i-1] 14 *s = (*s)[:i-1] 15 return n 16 } 17 18 // push inserts a node 19 func (s *tokenStack) push(n *htmlx.Token) { 20 i := len(*s) 21 (*s) = append(*s, nil) 22 (*s)[i] = n 23 } 24 25 // top returns the most recently pushed node, or nil if s is empty. 26 func (s *tokenStack) top() *htmlx.Token { 27 if i := len(*s); i > 0 { 28 return (*s)[i-1] 29 } 30 return nil 31 } 32 33 // index returns the index of the top-most occurrence of n in the stack, or -1 34 // if n is not present. 35 func (s *tokenStack) index(n *htmlx.Token) int { 36 for i := len(*s) - 1; i >= 0; i-- { 37 if (*s)[i] == n { 38 return i 39 } 40 } 41 return -1 42 } 43 44 // insert inserts a node at the given index. 45 func (s *tokenStack) insert(i int, n *htmlx.Token) { 46 (*s) = append(*s, nil) 47 copy((*s)[i+1:], (*s)[i:]) 48 (*s)[i] = n 49 } 50 51 // remove removes a node from the stack. It is a no-op if n is not present. 52 func (s *tokenStack) remove(n *htmlx.Token) { 53 i := s.index(n) 54 if i == -1 { 55 return 56 } 57 copy((*s)[i:], (*s)[i+1:]) 58 j := len(*s) - 1 59 (*s)[j] = nil 60 *s = (*s)[:j] 61 }