stack.go 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. package glisp
  2. import (
  3. "errors"
  4. "fmt"
  5. )
  6. type StackElem interface {
  7. IsStackElem()
  8. }
  9. type Stack struct {
  10. tos int
  11. elements []StackElem
  12. }
  13. func NewStack(size int) *Stack {
  14. stack := new(Stack)
  15. stack.tos = -1
  16. stack.elements = make([]StackElem, size)
  17. return stack
  18. }
  19. func (stack *Stack) Clone() *Stack {
  20. ret := &Stack{}
  21. ret.tos = stack.tos
  22. ret.elements = make([]StackElem, len(stack.elements))
  23. for i := range stack.elements {
  24. ret.elements[i] = stack.elements[i]
  25. }
  26. return ret
  27. }
  28. func (stack *Stack) Top() int {
  29. return stack.tos
  30. }
  31. func (stack *Stack) PushAllTo(target *Stack) int {
  32. if stack.tos < 0 {
  33. return 0
  34. }
  35. for _, v := range stack.elements[0 : stack.tos+1] {
  36. target.Push(v)
  37. }
  38. return stack.tos + 1
  39. }
  40. func (stack *Stack) IsEmpty() bool {
  41. return stack.tos < 0
  42. }
  43. func (stack *Stack) Push(elem StackElem) {
  44. stack.tos++
  45. if stack.tos == len(stack.elements) {
  46. stack.elements = append(stack.elements, elem)
  47. } else {
  48. stack.elements[stack.tos] = elem
  49. }
  50. }
  51. func (stack *Stack) Get(n int) (StackElem, error) {
  52. if stack.tos-n < 0 {
  53. return nil, errors.New(fmt.Sprint("invalid stack access asked for ", n, " Top was ", stack.tos))
  54. }
  55. return stack.elements[stack.tos-n], nil
  56. }
  57. func (stack *Stack) Pop() (StackElem, error) {
  58. elem, err := stack.Get(0)
  59. if err != nil {
  60. return nil, err
  61. }
  62. stack.tos--
  63. return elem, nil
  64. }
  65. func (stack *Stack) IsStackElem() {}