1package ini
2
3import (
4	"bytes"
5	"fmt"
6)
7
8// ParseStack is a stack that contains a container, the stack portion,
9// and the list which is the list of ASTs that have been successfully
10// parsed.
11type ParseStack struct {
12	top       int
13	container []AST
14	list      []AST
15	index     int
16}
17
18func newParseStack(sizeContainer, sizeList int) ParseStack {
19	return ParseStack{
20		container: make([]AST, sizeContainer),
21		list:      make([]AST, sizeList),
22	}
23}
24
25// Pop will return and truncate the last container element.
26func (s *ParseStack) Pop() AST {
27	s.top--
28	return s.container[s.top]
29}
30
31// Push will add the new AST to the container
32func (s *ParseStack) Push(ast AST) {
33	s.container[s.top] = ast
34	s.top++
35}
36
37// MarkComplete will append the AST to the list of completed statements
38func (s *ParseStack) MarkComplete(ast AST) {
39	s.list[s.index] = ast
40	s.index++
41}
42
43// List will return the completed statements
44func (s ParseStack) List() []AST {
45	return s.list[:s.index]
46}
47
48// Len will return the length of the container
49func (s *ParseStack) Len() int {
50	return s.top
51}
52
53func (s ParseStack) String() string {
54	buf := bytes.Buffer{}
55	for i, node := range s.list {
56		buf.WriteString(fmt.Sprintf("%d: %v\n", i+1, node))
57	}
58
59	return buf.String()
60}
61