Began implementing the stack and the stack stack

This commit is contained in:
Julien Dessaux 2021-09-21 00:28:31 +02:00
parent 309dcb5a02
commit 11dac6494d
3 changed files with 178 additions and 0 deletions

44
pkg/stack/stack-stack.go Normal file
View file

@ -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()
}

51
pkg/stack/stack.go Normal file
View file

@ -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)
}

83
pkg/stack/stack_test.go Normal file
View file

@ -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)
}