#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
/* ----- Type system ----- */
typedef enum {
T_INT,
T_DOUBLE,
T_STRING
} Type;
typedef struct {
void *data;
Type type;
} TypedValue;
/* ----- Node + Stack ----- */
typedef struct Node {
TypedValue value;
struct Node *next;
} Node;
typedef struct {
Node *top;
} Stack;
/* ----- Stack operations ----- */
void stack_init(Stack *s) {
s->top = NULL;
}
bool stack_empty(Stack *s) {
return s->top == NULL;
}
/* Push: takes ownership of TypedValue.data */
bool stack_push(Stack *s, TypedValue v) {
Node *n = malloc(sizeof(Node));
if (!n)
return false;
n->value = v;
n->next = s->top;
s->top = n;
return true;
}
/* Pop: returns TypedValue; caller must free value.data */
TypedValue stack_pop(Stack *s) {
TypedValue out = { NULL, T_INT };
if (stack_empty(s))
return out;
Node *n = s->top;
out = n->value;
s->top = n->next;
free(n);
return out;
}
TypedValue stack_peek(Stack *s) {
if (stack_empty(s)) {
TypedValue empty = { NULL, T_INT };
return empty;
}
return s->top->value;
}
/* Print a single TypedValue */
void print_value(TypedValue v) {
switch (v.type) {
case T_INT:
printf("%d ", *(int*)v.data);
break;
case T_DOUBLE:
printf("%.5f ", *(double*)v.data);
break;
case T_STRING:
printf("%s ", (char*)v.data);
break;
}
}
/* Print entire stack */
void stack_print(Stack *s) {
printf("Stack (top → bottom): ");
for (Node *n = s->top; n != NULL; n = n->next)
print_value(n->value);
printf("\n");
}
/* Free all nodes AND their data */
void stack_clear(Stack *s) {
while (!stack_empty(s)) {
TypedValue v = stack_pop(s);
free(v.data);
}
}
/* ----- main ----- */
int main(void) {
Stack s;
stack_init(&s);
/* Push int */
int *a = malloc(sizeof(int));
*a = 42;
stack_push(&s, (TypedValue){ a, T_INT });
/* Push double */
double *b = malloc(sizeof(double));
*b = 3.14159;
stack_push(&s, (TypedValue){ b, T_DOUBLE });
/* Push string */
char *c = malloc(20);
snprintf(c, 20, "hello");
stack_push(&s, (TypedValue){ c, T_STRING });
stack_print(&s);
/* Pop one */
TypedValue v = stack_pop(&s);
printf("Popped: ");
print_value(v);
printf("\n");
free(v.data);
stack_print(&s);
stack_clear(&s);
return 0;
}
/*
run:
Stack (top → bottom): hello 3.14159 42
Popped: hello
Stack (top → bottom): 3.14159 42
*/