aboutsummaryrefslogtreecommitdiff
path: root/pkg/stack/stack.go
blob: c3071330b77443429afec7e5e8cad585954c00cf (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
package stack

type Stack struct {
	size   int
	height int
	data   []int
	next   *Stack // Pointer to the next element in the stack stack
}

func NewStack(size int, next *Stack) *Stack {
	return &Stack{
		size:   size,
		height: 0,
		data:   make([]int, size),
		next:   next,
	}
}

func (s *Stack) Clear() {
	s.height = 0
}

func (s *Stack) Duplicate() {
	if s.height > 0 {
		s.Push(s.data[s.height-1])
	} else {
		s.Push(0)
		s.Push(0)
	}
}

func (s *Stack) Pop() int {
	if s.height > 0 {
		s.height--
		return s.data[s.height]
	}
	return 0
}

func (s *Stack) Push(value int) {
	if s.height >= s.size {
		s.size += 32
		s.data = append(s.data, make([]int, 32)...)
	}
	s.data[s.height] = value
	s.height++
}

func (s *Stack) Swap() {
	a := s.Pop()
	b := s.Pop()
	s.Push(a)
	s.Push(b)
}

func (s Stack) GetHeights() []int {
	if s.next != nil {
		return append(s.next.GetHeights(), s.height)
	} else {
		return []int{s.height}
	}
}

func (toss *Stack) Transfert(soss *Stack, n int) {
	// Implements a value transfert between two stacks, intended for use with the '{'
	// (aka begin) and '}' (aka end) stackstack commands
	toss.height += n
	if toss.height > toss.size {
		toss.data = append(toss.data, make([]int, toss.height-toss.size)...)
		toss.size = toss.height
	}
	for i := 1; i <= min(soss.height, n); i++ {
		toss.data[toss.height-i] = soss.data[soss.height-i]
		for i := min(soss.height, n) + 1; i <= n; i++ {
			toss.data[toss.height-i] = 0
		}
	}
	soss.height -= n
	if soss.height < 0 {
		soss.height = 0
	}
}

func (s Stack) Next() *Stack {
	return s.next
}

func (s *Stack) Discard(n int) {
	// Implements a discard mechanism intended for use with the '}'(aka end) stackstack command
	s.height -= n
	if s.height < 0 {
		s.height = 0
	}
}

func (s *Stack) YCommandPick(n int, h int) {
	if n > s.height {
		s.height = 1
		s.data[0] = 0
	} else {
		v := s.data[s.height-n]
		s.height = h
		s.Push(v)
	}
}