stack.go 1.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. package rt
  2. import "container/list"
  3. type Wait int
  4. const (
  5. WRONG Wait = iota
  6. SKIP
  7. STOP
  8. DO
  9. )
  10. type Stack interface {
  11. Push(frame Frame)
  12. Pop() Frame
  13. Top() Frame
  14. }
  15. type Frame interface {
  16. Do() (wait Wait)
  17. OnPush()
  18. OnPop()
  19. }
  20. func NewStack() Stack {
  21. return new(stdStack).Init()
  22. }
  23. type stdStack struct {
  24. inner list.List
  25. }
  26. func (s *stdStack) Init() *stdStack {
  27. s.inner = *list.New()
  28. return s
  29. }
  30. func (s *stdStack) Push(frame Frame) {
  31. s.inner.PushFront(frame)
  32. frame.OnPush()
  33. }
  34. func (s *stdStack) Pop() (frame Frame) {
  35. if s.inner.Front() != nil {
  36. elem := s.inner.Front()
  37. frame = elem.Value.(Frame)
  38. s.inner.Remove(elem)
  39. frame.OnPop()
  40. } else {
  41. panic("it's empty stack")
  42. }
  43. return frame
  44. }
  45. func (s *stdStack) Top() (frame Frame) {
  46. elem := s.inner.Front()
  47. if elem != nil {
  48. frame = elem.Value.(Frame)
  49. }
  50. return frame
  51. }
  52. func (w Wait) String() string {
  53. switch w {
  54. case DO:
  55. return "DO"
  56. case SKIP:
  57. return "SKIP"
  58. case STOP:
  59. return "STOP"
  60. case WRONG:
  61. return "WRONG"
  62. default:
  63. panic("wrong wait value")
  64. }
  65. }