Archived
1
0
Fork 0

Implemented the funge stack

This commit is contained in:
Julien Dessaux 2021-10-04 00:10:06 +02:00
parent e80fe27900
commit cdc3ec2044
2 changed files with 200 additions and 0 deletions

69
src/stack.nim Normal file
View file

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

131
tests/stack.nim Normal file
View file

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