aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulien Dessaux2021-10-04 00:10:06 +0200
committerJulien Dessaux2021-10-04 00:10:06 +0200
commitcdc3ec20443e5c9455359921801b2dabec7906a3 (patch)
treede55bf508da84085ad40e0d547876f037356c5bc
parentRefactoring (diff)
downloadnimfunge98-cdc3ec20443e5c9455359921801b2dabec7906a3.tar.gz
nimfunge98-cdc3ec20443e5c9455359921801b2dabec7906a3.tar.bz2
nimfunge98-cdc3ec20443e5c9455359921801b2dabec7906a3.zip
Implemented the funge stack
-rw-r--r--src/stack.nim69
-rw-r--r--tests/stack.nim131
2 files changed, 200 insertions, 0 deletions
diff --git a/src/stack.nim b/src/stack.nim
new file mode 100644
index 0000000..2c6826d
--- /dev/null
+++ b/src/stack.nim
@@ -0,0 +1,69 @@
+type
+ Stack* = object
+ size, height: int
+ data: seq[int]
+ next: ref Stack
+
+func NewStack*(size: int = 32, next: ref Stack = nil): ref Stack =
+ result = new(Stack)
+ result.size = size
+ result.data.setlen(size)
+ result.next = next
+
+func Pop*(s: var Stack): int =
+ if s.height > 0:
+ dec s.height
+ return s.data[s.height]
+ return 0
+
+func Push*(s: var Stack, v: int) =
+ if s.height >= s.size:
+ s.size += 32
+ s.data.setlen(s.size)
+ s.data[s.height] = v
+ inc s.height
+
+func PopVector*(s: var Stack): (int, int) =
+ if s.height >= 2:
+ s.height -= 2
+ return (s.data[s.height], s.data[s.height+1])
+ elif s.height == 1:
+ s.height = 0
+ return (0, s.data[0])
+ else:
+ return (0, 0)
+
+func PushVector*(s: var Stack, v: tuple[x, y: int]) =
+ if s.height+1 >= s.size:
+ s.size += 32
+ s.data.setlen(s.size)
+ s.data[s.height] = v.x
+ inc s.height
+ s.data[s.height] = v.y
+ inc s.height
+
+func Clear*(s: var Stack) =
+ s.height = 0
+
+func Duplicate*(s: var Stack) =
+ if s.height > 0:
+ s.Push(s.data[s.height-1])
+ else:
+ s.PushVector((0, 0))
+
+func Swap*(s: var Stack) =
+ let a = s.Pop
+ let b = s.Pop
+ s.Push(a)
+ s.Push(b)
+
+func Transfert*(toss: var Stack, soss: var Stack, n: int) =
+ toss.height += n
+ for i in 1..min(soss.height, n):
+ toss.data[toss.height-i] = soss.data[soss.height-i]
+ soss.height -= n
+ if soss.height < 0:
+ soss.height = 0
+
+func Next*(s: Stack): ref Stack =
+ return s.next
diff --git a/tests/stack.nim b/tests/stack.nim
new file mode 100644
index 0000000..469c425
--- /dev/null
+++ b/tests/stack.nim
@@ -0,0 +1,131 @@
+import unittest
+
+include ../src/stack
+
+suite "Stack":
+ test "Pop":
+ var empty = NewStack()
+ check empty[].Pop() == 0
+ var simple = NewStack()
+ simple.data[0] = 1
+ simple.data[1] = 5
+ simple.height = 2
+ check simple[].Pop() == 5
+ check simple[].Pop() == 1
+ check simple[].Pop() == 0
+ test "Push":
+ var s = NewStack()
+ check s.height == 0
+ check s.data[0] == 0
+ check s.data[1] == 0
+ check s.data[2] == 0
+ s[].Push(5)
+ check s.height == 1
+ check s.data[0] == 5
+ check s.data[1] == 0
+ check s.data[2] == 0
+ s[].Push(-2)
+ check s.height == 2
+ check s.data[0] == 5
+ check s.data[1] == -2
+ check s.data[2] == 0
+ test "PopVector":
+ var empty = NewStack()
+ check empty[].PopVector() == (0, 0)
+ check empty.height == 0
+ var some = NewStack()
+ some[].Push(2)
+ check some[].PopVector() == (0, 2)
+ check some.height == 0
+ var full = NewStack()
+ full[].Push(1)
+ full[].Push(2)
+ full[].Push(3)
+ check full[].PopVector() == (2, 3)
+ check full.height == 1
+ test "PushVector":
+ var s = NewStack()
+ check s.height == 0
+ check s.data[0] == 0
+ check s.data[1] == 0
+ check s.data[2] == 0
+ s[].PushVector((5, -3))
+ check s.height == 2
+ check s.data[0] == 5
+ check s.data[1] == -3
+ check s.data[2] == 0
+ test "Clear":
+ var empty: Stack
+ empty.Clear()
+ check empty.height == 0
+ var some = NewStack()
+ some[].Push(1)
+ some[].Push(2)
+ some[].Clear()
+ check some.height == 0
+ test "Duplicate":
+ var empty = NewStack()
+ empty[].Duplicate()
+ check empty.height == 2
+ check empty.data[0] == 0
+ check empty.data[1] == 0
+ var some = NewStack()
+ some[].Push(2)
+ some[].Push(-4)
+ some[].Duplicate()
+ check some.height == 3
+ check some.data[0] == 2
+ check some.data[1] == -4
+ check some.data[2] == -4
+ check some.data[3] == 0
+ test "Swap":
+ var empty = NewStack()
+ empty[].Swap()
+ check empty.height == 2
+ check empty.data[0] == 0
+ check empty.data[1] == 0
+ var some = NewStack()
+ some[].Push(2)
+ some[].Push(-4)
+ some[].Push(7)
+ some[].Swap()
+ check some.height == 3
+ check some.data[0] == 2
+ check some.data[1] == 7
+ check some.data[2] == -4
+ check some.data[3] == 0
+ test "Transfert":
+ var empty = NewStack()
+ var empty2 = NewStack()
+ empty[].Transfert(empty2[], 4)
+ check empty.height == 4
+ check empty2.height == 0
+ check empty.data[0] == 0
+ check empty.data[1] == 0
+ check empty.data[2] == 0
+ check empty.data[3] == 0
+ empty = NewStack()
+ var some = NewStack()
+ some[].Push(2)
+ empty[].Transfert(some[], 3)
+ check empty.height == 3
+ check some.height == 0
+ check empty.data[0] == 0
+ check empty.data[1] == 0
+ check empty.data[2] == 2
+ empty = NewStack()
+ var full = NewStack()
+ full[].Push(1)
+ full[].Push(2)
+ full[].Push(3)
+ empty[].Transfert(full[], 2)
+ check empty.height == 2
+ check full.height == 1
+ check full.data[0] == 1
+ check empty.data[0] == 2
+ check empty.data[1] == 3
+ test "Next":
+ var empty = NewStack()
+ check empty[].Next() == nil
+ var some = NewStack(next=empty)
+ check some[].Next() == empty