import "./option.zc" import "./mem.zc" struct Stack { data: T*; len: usize; cap: usize; } impl Stack { fn new() -> Stack { return Stack{data: NULL, len: 0, cap: 0}; } fn free(self) { if (self.data) { free(self.data); self.data = NULL; } self.len = 0; } fn clone(self) -> Stack { var new_stack = Stack::new(); new_stack.len = self.len; new_stack.cap = self.cap; new_stack.data = malloc(sizeof(T) * new_stack.cap); memcpy(new_stack.data, self.data, sizeof(T) * new_stack.cap); return new_stack; } fn push(self, value: T) { if (!self.data) { self.cap = 8; self.data = malloc(sizeof(T) * self.cap); } if (self.len == self.cap) { self.cap = self.cap * 2; self.data = realloc(self.data, sizeof(T) * self.cap); } self.data[self.len] = value; self.len = self.len + 1; } fn pop(self) -> Option { if (self.len > 0) { var value = self.data[self.len - 1]; self.len = self.len - 1; return Option::Some(value); } return Option::None(); } fn length(self) -> usize { return self.len; } fn clear(self) { self.len = 0; } fn is_empty(self) -> bool { return self.len == 0; } } impl Drop for Stack { fn drop(self) { self.free(); } }