# Implementation of a stack using a linked list.

fun Stack_New(T) {
	if T == None:
		return none, "The type can't be None";
	return { count: 0, head: none, type: T };
}

fun Stack_Push(stack: Map, value) {
	
	assert(stack.type != None);

	if type(value) != stack.type:
		error("Invalid type");

	node = {prev: none, item: value};

	node.prev = stack.head;
	stack.head = node;
	stack.count = stack.count + 1;
}

fun Stack_Pop(stack: Map) {

	if stack.head == none:
		return none;
	
	value = stack.head.item;
	stack.head = stack.head.prev;
	stack.count = stack.count - 1;

	return value;
}

fun Stack_Print(stack: Map) {
	print("[");
	curr = stack.head;
	while curr != none: {
		print(curr.item);
		curr = curr.prev;
		if curr != none:
			print(", ");
	}
	print("]");
}

stack = Stack_New(int);

Stack_Push(stack, 1);
Stack_Push(stack, 2);
Stack_Push(stack, 3);

Stack_Print(stack);
print("\n");

x = Stack_Pop(stack);
y = Stack_Pop(stack);
z = Stack_Pop(stack);
w = Stack_Pop(stack);

assert(x == 3);
assert(y == 2);
assert(z == 1);
assert(w == none);

Stack_Print(stack);
print("\n");
