aboutsummaryrefslogtreecommitdiff
path: root/pkg/pointer/stack-stack.go
diff options
context:
space:
mode:
authorJulien Dessaux2021-09-23 11:45:49 +0200
committerJulien Dessaux2021-09-23 11:45:49 +0200
commit759ee2aa10323d1960405c93f7cd4cf6d383ae7a (patch)
tree87648b4811b0264f1b54c454ed2569abe1abee94 /pkg/pointer/stack-stack.go
parentBegan coding the interpreter (only manages the minimal example for now!) (diff)
downloadgofunge98-759ee2aa10323d1960405c93f7cd4cf6d383ae7a.tar.gz
gofunge98-759ee2aa10323d1960405c93f7cd4cf6d383ae7a.tar.bz2
gofunge98-759ee2aa10323d1960405c93f7cd4cf6d383ae7a.zip
Each pointer needs its own stack, merging the two packages to avoid a circular dependency
Diffstat (limited to 'pkg/pointer/stack-stack.go')
-rw-r--r--pkg/pointer/stack-stack.go95
1 files changed, 95 insertions, 0 deletions
diff --git a/pkg/pointer/stack-stack.go b/pkg/pointer/stack-stack.go
new file mode 100644
index 0000000..6d22f51
--- /dev/null
+++ b/pkg/pointer/stack-stack.go
@@ -0,0 +1,95 @@
+package pointer
+
+type StackStack struct {
+ head *Stack
+ height int
+}
+
+func NewStackStack() *StackStack {
+ return &StackStack{
+ head: NewStack(),
+ height: 1,
+ }
+}
+
+func (ss *StackStack) Begin(p *Pointer) {
+ ss.height++
+ soss := ss.head
+ n := soss.Pop()
+ np := n
+ if np < 0 {
+ np = -np
+ }
+ toss := &Stack{
+ size: np,
+ height: np,
+ data: make([]int, np),
+ next: soss,
+ }
+ ss.head = toss
+ max := n - soss.height
+ if max < 0 {
+ max = 0
+ }
+ for i := n - 1; i >= max; i-- {
+ toss.data[i] = soss.data[soss.height-n+i]
+ }
+ x, y := p.GetStorageOffset()
+ soss.Push(x)
+ soss.Push(y)
+ p.CalculateNewStorageOffset()
+}
+
+func (ss *StackStack) End(p *Pointer) (reflect bool) {
+ if ss.height == 1 {
+ return true
+ }
+ soss := ss.head.next
+ n := ss.head.Pop()
+ y := soss.Pop()
+ x := soss.Pop()
+ p.SetStorageOffset(x, y)
+ if n > 0 {
+ soss.height += n
+ if soss.size < soss.height {
+ soss.data = append(soss.data, make([]int, soss.height-soss.size)...)
+ soss.size = soss.height
+ }
+ for i := n; i > 0; i-- {
+ soss.data[soss.height-i] = ss.head.data[ss.head.height-i]
+ }
+ } else {
+ soss.height += n
+ if soss.height < 0 {
+ soss.height = 0
+ }
+ }
+ ss.height--
+ ss.head = ss.head.next
+ return false
+}
+
+func (ss *StackStack) Under() (reflect bool) {
+ if ss.height == 1 {
+ return true
+ }
+ n := ss.head.Pop()
+ if n > 0 {
+ for i := 0; i < n; i++ {
+ ss.head.Push(ss.head.next.Pop())
+ }
+ } else {
+ for i := 0; i < -n; i++ {
+ ss.head.next.Push(ss.head.Pop())
+ }
+ }
+ return false
+}
+
+func (ss StackStack) Pop() int {
+ return ss.head.Pop()
+}
+
+func (ss StackStack) Push(v int) {
+ ss.head.Push(v)
+}