Repository navigation
Expand file tree
/
Copy pathaddr_stack.go
More file actions
85 lines (72 loc) · 1.72 KB
/
Copy pathaddr_stack.go
File metadata and controls
85 lines (72 loc) · 1.72 KB
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
package glisp
import (
"fmt"
)
type Address struct {
function *SexpFunction
position int
}
type AddrStack struct {
tos int
elements []Address
}
func NewAddrStack(size int) *AddrStack {
stack := new(AddrStack)
stack.tos = -1
if count := size - cap(stack.elements); count > 0 {
stack.elements = append(stack.elements, make([]Address, count)...)
}
if count := size - len(stack.elements); count > 0 {
stack.elements = stack.elements[:cap(stack.elements)]
}
return stack
}
func (stack *AddrStack) Clone() *AddrStack {
ret := NewAddrStack(len(stack.elements))
ret.tos = stack.tos
for i := 0; i <= stack.tos; i++ {
ret.elements[i] = stack.elements[i]
}
return ret
}
func (stack *AddrStack) Top() int {
return stack.tos
}
func (stack *AddrStack) IsEmpty() bool {
return stack.tos < 0
}
func (stack *AddrStack) Push(elem Address) {
stack.tos++
if stack.tos == len(stack.elements) {
stack.elements = append(stack.elements, elem)
} else {
stack.elements[stack.tos] = elem
}
}
func (stack *AddrStack) Get(n int) (Address, error) {
if n < 0 || n > stack.tos {
return Address{}, fmt.Errorf("invalid stack access asked for %v Top was %v", n, stack.tos)
}
return stack.elements[stack.tos-n], nil
}
func (stack *AddrStack) Pop() (Address, error) {
elem, err := stack.Get(0)
if err != nil {
return Address{}, err
}
stack.elements[stack.tos] = Address{}
stack.tos--
return elem, nil
}
func (stack *AddrStack) PushAddr(function *SexpFunction, pc int) {
stack.Push(Address{function: function, position: pc})
}
func (stack *AddrStack) PopAddr() (fn *SexpFunction, pos int, err error) {
addr, err := stack.Pop()
if err != nil {
return MissingFunction, 0, err
}
fn = addr.function
pos = addr.position
return
}