+#include <stdlib.h>
+#include "stack.h"
+
+#define INIT_SIZE 100
+
+struct _Stack {
+ int size;
+ void** elems;
+ StackFreeFunc free;
+};
+
+static void free_elem(Stack* stack) {
+ if (stack->free) {
+ for (int i = 0; i < stack->size; i++)
+ stack->free(stack->elems[i]);
+ }
+ free(stack->elems);
+}
+
+static Stack* stack_new_common() {
+ Stack* s = malloc(sizeof(Stack));
+ s->elems = malloc(sizeof(void*) * INIT_SIZE);
+ s->size = 0;
+ s->free = NULL;
+ return s;
+}
+
+Stack* stack_new() {
+ return stack_new_common();
+}
+
+Stack* stack_new_full(StackFreeFunc free) {
+ Stack* s = stack_new_common();
+ s->free = free;
+ return s;
+}
+
+void stack_destroy(Stack* stack) {
+ free_elem(stack);
+ free(stack);
+}
+
+void* stack_pop(Stack* stack) {
+ if (stack_empty(stack))
+ return NULL;
+ stack->size -= 1;
+ void* elem = stack->elems[stack->size];
+ stack->elems[stack->size] = NULL;
+
+ return elem;
+}
+
+void stack_push(Stack* stack, void* elem) {
+ if (stack == NULL)
+ return;
+
+ stack->size += 1;
+ if (stack->size == INIT_SIZE) {
+ stack->elems = realloc(stack->elems, (INIT_SIZE + stack->size) * sizeof(void*));
+ }
+
+ stack->elems[stack->size - 1] = elem;
+}
+
+void* stack_peek(Stack* stack) {
+ if (stack_empty(stack))
+ return NULL;
+ return stack->elems[stack->size - 1];
+}
+
+bool stack_empty(Stack* stack) {
+ return (stack == NULL || stack->size == 0);
+}
+
+void stack_clear(Stack* stack) {
+ if (stack == NULL)
+ return;
+
+ free_elem(stack);
+ stack->size = 0;
+}
+
+int stack_size(Stack* stack) {
+ if (stack_empty(stack))
+ return 0;
+ return stack->size;
+}
+
+/*
+typedef struct _Stack {
+ void** elems;
+ int size;
+ StackFreeFunc free;
+} Stack;
+
+static void free_elem(Stack* stack) {
+ if (stack->free) {
+ for (int i = 0; i < stack->size; i++)
+ stack->free(stack->elems[i]);
+ }
+ free(stack->elems);
+}
+
+Stack* stack_new() {
+ Stack* s = malloc(sizeof(Stack));
+ s->size = 0;
+ s->elems = NULL;
+ s->free = NULL;
+ return s;
+}
+
+Stack* stack_new_full(StackFreeFunc free) {
+ Stack* s = malloc(sizeof(Stack));
+ s->size = 0;
+ s->elems = NULL;
+ s->free = free;
+ return s;
+}
+
+void stack_destroy(Stack* stack) {
+ free_elem(stack);
+ free(stack);
+}
+
+void* stack_pop(Stack* stack) {
+ if (stack_empty(stack))
+ return NULL;
+ stack->size -= 1;
+ void* elem = stack->elems[stack->size];
+ stack->elems[stack->size] = NULL;
+ stack->elems = realloc(stack->elems, stack->size * sizeof(void*));
+
+ return elem;
+}
+
+void stack_push(Stack* stack, void* elem) {
+ if (stack == NULL)
+ return;
+
+ stack->size += 1;
+ stack->elems = realloc(stack->elems, stack->size * sizeof(void*));
+ stack->elems[stack->size - 1] = elem;
+}
+
+void* stack_peek(Stack* stack) {
+ if (stack_empty(stack))
+ return NULL;
+ return stack->elems[stack->size - 1];
+}
+
+bool stack_empty(Stack* stack) {
+ return (stack == NULL || stack->size == 0);
+}
+
+void stack_clear(Stack* stack) {
+ if (stack == NULL)
+ return;
+
+ free_elem(stack);
+ stack->size = 0;
+ stack->elems = NULL;
+}
+
+int stack_size(Stack* stack) {
+ if (stack_empty(stack))
+ return 0;
+ return stack->size;
+}
+*/