Skip to content

Instantly share code, notes, and snippets.

@stpettersens
Last active June 18, 2026 14:19
Show Gist options
  • Select an option

  • Save stpettersens/5a42682dcb5cc0fc43751df973fe20df to your computer and use it in GitHub Desktop.

Select an option

Save stpettersens/5a42682dcb5cc0fc43751df973fe20df to your computer and use it in GitHub Desktop.
Simple stack implemented around list in C3
module stack<Type>;
import std::collections;
/* A stack implemented around a list */
struct Stack {
List{Type} items;
int size;
}
fn Stack new() {
Stack stack = {};
stack.items = {};
stack.size = 0;
return stack;
}
fn void Stack.push(Stack* stack, Type item) {
stack.items.push(item);
++stack.size;
}
fn void Stack.push_all(Stack* stack, Type[] items) {
foreach (item : items) {
stack.items.push(item);
++stack.size;
}
}
fn Type Stack.peek(Stack* stack) {
assert(stack.size > 0);
Type peeked = stack.items[--stack.size];
++stack.size;
return peeked;
}
fn Type Stack.peek_at_index(Stack *stack, int idx) {
assert(stack.size > 0);
assert(idx >= 0 && idx < stack.size);
return stack.items[idx];
}
fn Type Stack.pop(Stack* stack) {
assert(stack.size > 0);
Type last = stack.items[--stack.size];
stack.items.remove_at(stack.size);
return last;
}
fn Type Stack.pop_first(Stack* stack) {
assert(stack.size > 0);
Type first = stack.items[0];
stack.items.remove_at(0);
--stack.size;
return first;
}
fn void Stack.clear(Stack* stack) {
stack.items.clear();
stack.size = 0;
}
fn int Stack.get_count(Stack* stack) {
if (stack.size < 0) stack.size = 0;
return stack.size;
}
fn bool Stack.is_empty(Stack* stack) {
if (stack.size < 0) stack.size = 0;
return stack.size == 0;
}
fn List{Type} Stack.get_items(Stack* stack) {
return stack.items;
}
module stack_test;
import stack;
import util;
import util::id;
import std::io;
import std::collections;
alias Id = String;
alias IntStack = Stack{int};
alias IdStack = Stack{Id};
fn void do_int_stack() {
io::printn("Do an integer stack...");
IntStack s = stack::new();
io::printfn("Stack count = %d", s.get_count());
io::printfn("Adding 1, 2, 3 to the stack...");
int i = 1;
while (i <= 3) {
s.push(i);
io::printfn("Pushed %d", i);
i++;
}
io::printfn("peek at index 0: %d", s.peek_at_index(0));
io::printfn("peek %d", s.peek());
io::printfn("pop %d", s.pop());
io::printfn("peek %d", s.peek());
io::printfn("pop %d", s.pop());
io::printfn("Stack count = %d", s.get_count());
io::printn("Clear the stack...");
s.clear();
io::printfn("Stack count = %d", s.get_count());
io::printfn("The stack is empty? %s", util::bool_str(s.is_empty()));
io::printn();
}
fn void do_id_stack() {
io::printn("Do an Id stack...");
IdStack s = stack::new();
io::printfn("Stack count = %d", s.get_count());
io::printfn("Adding Ids to the stack...");
const long ID_LENGTH = 16;
Id[*] ids = {
id::generate_id(ID_LENGTH),
id::generate_id(ID_LENGTH),
id::generate_id(ID_LENGTH)
};
s.push_all(&ids);
io::printfn("The stack is empty? %s", util::bool_str(s.is_empty()));
io::printfn("Stack count = %d", s.get_count());
io::printfn("peek at index 2: '%s'", s.peek_at_index(2));
io::printfn("pop '%s'", s.pop());
io::printfn("peek '%s'", s.peek());
io::printfn("pop first '%s'", s.pop_first());
io::printfn("Stack count = %d", s.get_count());
io::printfn("pop '%s'", s.pop());
io::printfn("Stack count = %d", s.get_count());
io::printfn("The stack is empty? %s", util::bool_str(s.is_empty()));
io::printn();
}
fn int main() {
do_int_stack();
do_id_stack();
return 0;
}
@stpettersens

Copy link
Copy Markdown
Author

The test makes use of the util library,

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment