Implemented the stackstack
This commit is contained in:
parent
0188cd49fe
commit
1d11df68fc
4 changed files with 180 additions and 0 deletions
|
@ -58,12 +58,24 @@ func Swap*(s: var Stack) =
|
||||||
s.Push(b)
|
s.Push(b)
|
||||||
|
|
||||||
func Transfert*(toss: var Stack, soss: var Stack, n: int) =
|
func Transfert*(toss: var Stack, soss: var Stack, n: int) =
|
||||||
|
## Implements a value transfert between two stacks, intended for use with the '{'
|
||||||
|
## (aka begin) and '}' (aka end) stackstack commands
|
||||||
toss.height += n
|
toss.height += n
|
||||||
|
if toss.height > toss.size:
|
||||||
|
toss.size += 32
|
||||||
|
toss.data.setlen(toss.size)
|
||||||
for i in 1..min(soss.height, n):
|
for i in 1..min(soss.height, n):
|
||||||
toss.data[toss.height-i] = soss.data[soss.height-i]
|
toss.data[toss.height-i] = soss.data[soss.height-i]
|
||||||
|
for i in min(soss.height, n)+1..n:
|
||||||
|
toss.data[toss.height-i] = 0
|
||||||
soss.height -= n
|
soss.height -= n
|
||||||
if soss.height < 0:
|
if soss.height < 0:
|
||||||
soss.height = 0
|
soss.height = 0
|
||||||
|
|
||||||
|
func Discard*(s: var Stack, n: int) =
|
||||||
|
s.height -= n
|
||||||
|
if s.height < 0:
|
||||||
|
s.height = 0
|
||||||
|
|
||||||
func Next*(s: Stack): ref Stack =
|
func Next*(s: Stack): ref Stack =
|
||||||
return s.next
|
return s.next
|
||||||
|
|
57
src/stackStack.nim
Normal file
57
src/stackStack.nim
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
import stack
|
||||||
|
|
||||||
|
type
|
||||||
|
StackStack* = object
|
||||||
|
height: int
|
||||||
|
head: ref Stack
|
||||||
|
|
||||||
|
func NewStackStack*(): ref StackStack =
|
||||||
|
result = new(StackStack)
|
||||||
|
result.head = NewStack()
|
||||||
|
result.height = 1
|
||||||
|
|
||||||
|
func Pop*(ss: StackStack): int =
|
||||||
|
return ss.head[].Pop()
|
||||||
|
|
||||||
|
func Push*(ss: StackStack, v: int) =
|
||||||
|
ss.head[].Push(v)
|
||||||
|
|
||||||
|
func PopVector*(ss: StackStack): (int, int) =
|
||||||
|
return ss.head[].PopVector()
|
||||||
|
|
||||||
|
func PushVector*(ss: var StackStack, v: tuple[x, y: int]) =
|
||||||
|
ss.head[].PushVector(v)
|
||||||
|
|
||||||
|
func Clear*(ss: var StackStack) =
|
||||||
|
ss.head[].Clear()
|
||||||
|
|
||||||
|
func Begin*(ss: var StackStack, v: tuple[x, y: int]) =
|
||||||
|
inc ss.height
|
||||||
|
let soss = ss.head
|
||||||
|
let n = soss[].Pop()
|
||||||
|
ss.head = NewStack(size = abs(n), next = soss)
|
||||||
|
let toss = ss.head
|
||||||
|
if n > 0:
|
||||||
|
toss[].Transfert(soss[], n)
|
||||||
|
elif n < 0:
|
||||||
|
for i in 0 ..< -n:
|
||||||
|
soss[].Push(0)
|
||||||
|
soss[].PushVector(v)
|
||||||
|
|
||||||
|
func End*(ss: var StackStack, v: var tuple[x, y: int]): bool =
|
||||||
|
## Implements the '}' command behaviour which pops a stack from the stack stack
|
||||||
|
## returns true if a reflect should happen
|
||||||
|
if ss.height == 1:
|
||||||
|
return true
|
||||||
|
let toss = ss.head
|
||||||
|
let soss = toss[].Next()
|
||||||
|
let n = toss[].Pop()
|
||||||
|
v.y = soss[].Pop()
|
||||||
|
v.x = soss[].Pop()
|
||||||
|
if n > 0:
|
||||||
|
soss[].Transfert(toss[], n)
|
||||||
|
else:
|
||||||
|
soss[].Discard(-n)
|
||||||
|
dec ss.height
|
||||||
|
ss.head = soss
|
||||||
|
return false
|
|
@ -130,6 +130,13 @@ suite "Stack":
|
||||||
check full.data[0] == 1
|
check full.data[0] == 1
|
||||||
check empty.data[0] == 2
|
check empty.data[0] == 2
|
||||||
check empty.data[1] == 3
|
check empty.data[1] == 3
|
||||||
|
test "Discard":
|
||||||
|
var empty = NewStack()
|
||||||
|
empty[].Discard(1)
|
||||||
|
check empty.height == 0
|
||||||
|
empty[].Push(2)
|
||||||
|
empty[].Discard(3)
|
||||||
|
check empty.height == 0
|
||||||
test "Next":
|
test "Next":
|
||||||
var empty = NewStack()
|
var empty = NewStack()
|
||||||
check empty[].Next() == nil
|
check empty[].Next() == nil
|
||||||
|
|
104
tests/stackStack.nim
Normal file
104
tests/stackStack.nim
Normal file
|
@ -0,0 +1,104 @@
|
||||||
|
import unittest
|
||||||
|
|
||||||
|
include ../src/stackStack
|
||||||
|
|
||||||
|
suite "StackStack":
|
||||||
|
test "Pop":
|
||||||
|
var empty = NewStackStack()
|
||||||
|
check empty[].Pop() == 0
|
||||||
|
test "Push":
|
||||||
|
var empty = NewStackStack()
|
||||||
|
empty[].Push(5)
|
||||||
|
check empty[].Pop() == 5
|
||||||
|
test "PopVector":
|
||||||
|
var empty = NewStackStack()
|
||||||
|
check empty[].PopVector() == (0, 0)
|
||||||
|
test "PushVector":
|
||||||
|
var empty = NewStackStack()
|
||||||
|
empty[].PushVector((3, 2))
|
||||||
|
check empty[].PopVector() == (3, 2)
|
||||||
|
test "Clear":
|
||||||
|
var empty = NewStackStack()
|
||||||
|
empty[].Push(3)
|
||||||
|
empty[].Clear()
|
||||||
|
check empty[].Pop() == 0
|
||||||
|
test "Begin":
|
||||||
|
var empty = NewStackStack()
|
||||||
|
empty[].Begin((1, 2))
|
||||||
|
check empty.height == 2
|
||||||
|
check empty[].Pop() == 0
|
||||||
|
empty[].Push(5)
|
||||||
|
empty[].Push(6)
|
||||||
|
empty[].Push(4)
|
||||||
|
empty[].Begin((3, 4))
|
||||||
|
check empty.height == 3
|
||||||
|
check empty[].Pop() == 6
|
||||||
|
check empty[].Pop() == 5
|
||||||
|
check empty[].Pop() == 0
|
||||||
|
check empty[].Pop() == 0
|
||||||
|
empty[].Push(7)
|
||||||
|
empty[].Push(8)
|
||||||
|
empty[].Push(9)
|
||||||
|
empty[].Push(2)
|
||||||
|
empty[].Begin((10, 11))
|
||||||
|
check empty.height == 4
|
||||||
|
check empty[].Pop() == 9
|
||||||
|
check empty[].Pop() == 8
|
||||||
|
check empty[].Pop() == 0
|
||||||
|
empty[].Push(13)
|
||||||
|
empty[].Push(14)
|
||||||
|
empty[].Push(-2)
|
||||||
|
empty[].Begin((15, 16))
|
||||||
|
check empty[].Pop() == 0
|
||||||
|
test "End":
|
||||||
|
var empty = NewStackStack()
|
||||||
|
var v: tuple[x,y: int] = (0, 0)
|
||||||
|
empty[].Push(1)
|
||||||
|
check empty[].End(v) == true
|
||||||
|
check empty.height == 1
|
||||||
|
check empty[].Pop() == 1
|
||||||
|
empty[].Push(1)
|
||||||
|
empty[].Push(2)
|
||||||
|
empty[].Push(3)
|
||||||
|
empty[].Push(4)
|
||||||
|
empty[].Push(2)
|
||||||
|
v = (5, 6)
|
||||||
|
empty[].Begin(v)
|
||||||
|
v = (0, 0)
|
||||||
|
empty[].Push(2)
|
||||||
|
check empty[].End(v) == false
|
||||||
|
check v == (5, 6)
|
||||||
|
check empty.height == 1
|
||||||
|
check empty[].End(v) == true
|
||||||
|
check empty[].Pop() == 4
|
||||||
|
check empty[].Pop() == 3
|
||||||
|
check empty[].Pop() == 2
|
||||||
|
check empty[].Pop() == 1
|
||||||
|
empty[].Push(1)
|
||||||
|
empty[].Push(2)
|
||||||
|
empty[].Push(3)
|
||||||
|
empty[].Push(4)
|
||||||
|
empty[].Push(2)
|
||||||
|
empty[].Begin(v)
|
||||||
|
empty[].Push(4)
|
||||||
|
check empty[].End(v) == false
|
||||||
|
check v == (5, 6)
|
||||||
|
check empty.height == 1
|
||||||
|
check empty[].Pop() == 4
|
||||||
|
check empty[].Pop() == 3
|
||||||
|
check empty[].Pop() == 0
|
||||||
|
check empty[].Pop() == 0
|
||||||
|
check empty[].Pop() == 2
|
||||||
|
check empty[].Pop() == 1
|
||||||
|
empty[].Push(1)
|
||||||
|
empty[].Push(2)
|
||||||
|
empty[].Push(3)
|
||||||
|
empty[].Push(4)
|
||||||
|
empty[].Push(1)
|
||||||
|
empty[].Begin(v)
|
||||||
|
empty[].Push(-2)
|
||||||
|
check empty[].End(v) == false
|
||||||
|
check v == (5, 6)
|
||||||
|
check empty.height == 1
|
||||||
|
check empty[].Pop() == 1
|
||||||
|
check empty[].Pop() == 0
|
Reference in a new issue