From cdc3ec20443e5c9455359921801b2dabec7906a3 Mon Sep 17 00:00:00 2001 From: Julien Dessaux Date: Mon, 4 Oct 2021 00:10:06 +0200 Subject: Implemented the funge stack --- src/stack.nim | 69 +++++++++++++++++++++++++++++ tests/stack.nim | 131 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 200 insertions(+) create mode 100644 src/stack.nim create mode 100644 tests/stack.nim 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 -- cgit v1.2.3