diff options
author | Julien Dessaux | 2021-09-21 00:28:31 +0200 |
---|---|---|
committer | Julien Dessaux | 2021-09-21 00:28:31 +0200 |
commit | 11dac6494d90c73545f0a9e03732c6ef7bad88b7 (patch) | |
tree | 992e9d0c69c7e1cb26f85ee59c5234bba1d3e753 | |
parent | Continued implementing the Instruction Pointer (diff) | |
download | gofunge98-11dac6494d90c73545f0a9e03732c6ef7bad88b7.tar.gz gofunge98-11dac6494d90c73545f0a9e03732c6ef7bad88b7.tar.bz2 gofunge98-11dac6494d90c73545f0a9e03732c6ef7bad88b7.zip |
Began implementing the stack and the stack stack
-rw-r--r-- | pkg/stack/stack-stack.go | 44 | ||||
-rw-r--r-- | pkg/stack/stack.go | 51 | ||||
-rw-r--r-- | pkg/stack/stack_test.go | 83 |
3 files changed, 178 insertions, 0 deletions
diff --git a/pkg/stack/stack-stack.go b/pkg/stack/stack-stack.go new file mode 100644 index 0000000..db5a405 --- /dev/null +++ b/pkg/stack/stack-stack.go @@ -0,0 +1,44 @@ +package stack + +import ( + "git.adyxax.org/adyxax/gofunge/pkg/pointer" +) + +type StackStack struct { + head *Stack + height int +} + +func NewStackStack() *StackStack { + return &StackStack{ + head: NewStack(), + height: 1, + } +} + +func (ss *StackStack) Begin(p *pointer.Pointer) { + 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() +} diff --git a/pkg/stack/stack.go b/pkg/stack/stack.go new file mode 100644 index 0000000..4dbb72c --- /dev/null +++ b/pkg/stack/stack.go @@ -0,0 +1,51 @@ +package stack + +type Stack struct { + size int + height int + data []int + next *Stack // Pointer to the next element in the stack stack +} + +func NewStack() *Stack { + return &Stack{ + size: 32, + height: 0, + data: make([]int, 32), + next: nil, + } +} + +func (s *Stack) Clear() { + s.height = 0 +} + +func (s *Stack) Duplicate() { + if s.height > 0 { + s.Push(s.data[s.height-1]) + } +} + +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) +} diff --git a/pkg/stack/stack_test.go b/pkg/stack/stack_test.go new file mode 100644 index 0000000..d9e0cca --- /dev/null +++ b/pkg/stack/stack_test.go @@ -0,0 +1,83 @@ +package stack + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +func TestNewStack(t *testing.T) { + require.Equal(t, NewStack(), &Stack{ + size: 32, + height: 0, + data: make([]int, 32), + next: nil, + }) +} + +func TestClear(t *testing.T) { + s := NewStack() + s.Clear() + require.Equal(t, s.height, 0) +} + +func TestDupicate(t *testing.T) { + s := NewStack() + s2 := NewStack() + s.Duplicate() + require.Equal(t, s.height, s2.height) + s.Push(12) + s.Duplicate() + s2.Push(12) + s2.Push(12) + require.Equal(t, s.height, s2.height) + require.Equal(t, s.data, s2.data) +} + +func TestPop(t *testing.T) { + s := NewStack() + v := s.Pop() + require.Equal(t, v, 0) + s.Push(12) + s.Push(14) + v = s.Pop() + require.Equal(t, v, 14) + v = s.Pop() + require.Equal(t, v, 12) + v = s.Pop() + require.Equal(t, v, 0) +} + +func TestPush(t *testing.T) { + s := NewStack() + for i := 0; i < 32; i++ { + s.Push(i) + } + require.Equal(t, s.size, 32) + s.Push(-1) + require.Equal(t, s.size, 64) +} + +func TestSwap(t *testing.T) { + s := NewStack() + s2 := NewStack() + s.Swap() + s2.Push(0) + s2.Push(0) + require.Equal(t, s, s2) + s.Clear() + s.Push(1) + s.Swap() + s2.Clear() + s2.Push(1) + s2.Push(0) + require.Equal(t, s, s2) + s.Clear() + s.Push(1) + s.Push(2) + s2.Clear() + s2.Push(2) + s2.Push(1) + s.Swap() + require.Equal(t, s, s2) +} |