aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/stack.nim12
-rw-r--r--src/stackStack.nim57
-rw-r--r--tests/stack.nim7
-rw-r--r--tests/stackStack.nim104
4 files changed, 180 insertions, 0 deletions
diff --git a/src/stack.nim b/src/stack.nim
index 2c6826d..eeef5cd 100644
--- a/src/stack.nim
+++ b/src/stack.nim
@@ -58,12 +58,24 @@ func Swap*(s: var Stack) =
s.Push(b)
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
+ if toss.height > toss.size:
+ toss.size += 32
+ toss.data.setlen(toss.size)
for i in 1..min(soss.height, n):
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
if 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 =
return s.next
diff --git a/src/stackStack.nim b/src/stackStack.nim
new file mode 100644
index 0000000..6d32c87
--- /dev/null
+++ b/src/stackStack.nim
@@ -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
diff --git a/tests/stack.nim b/tests/stack.nim
index 0f7e4c8..cb49daf 100644
--- a/tests/stack.nim
+++ b/tests/stack.nim
@@ -130,6 +130,13 @@ suite "Stack":
check full.data[0] == 1
check empty.data[0] == 2
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":
var empty = NewStack()
check empty[].Next() == nil
diff --git a/tests/stackStack.nim b/tests/stackStack.nim
new file mode 100644
index 0000000..03650f8
--- /dev/null
+++ b/tests/stackStack.nim
@@ -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