148 lines
2.8 KiB
C
148 lines
2.8 KiB
C
#include <errno.h>
|
|
#include<stdio.h>
|
|
#include<stdlib.h>
|
|
|
|
typedef struct {
|
|
double* st;
|
|
int cnt;
|
|
int size;
|
|
} STACK;
|
|
|
|
STACK* init_stack(int size) {
|
|
if (size <= 0) {
|
|
return NULL;
|
|
}
|
|
STACK *buf;
|
|
buf = malloc(sizeof(STACK));
|
|
if (buf == NULL) {
|
|
fprintf(stderr, "Error allocating structure\n");
|
|
return NULL;
|
|
}
|
|
buf -> st = malloc(sizeof(int)*size);
|
|
if (buf -> st == NULL) {
|
|
fprintf(stderr, "Error allocating array\n");
|
|
free(buf);
|
|
return NULL;
|
|
}
|
|
buf -> cnt = 0;
|
|
buf -> size = size;
|
|
return buf;
|
|
}
|
|
|
|
void destroy_stack(STACK* s) {
|
|
free(s -> st);
|
|
free(s);
|
|
}
|
|
|
|
void push(STACK* st, double val) {
|
|
if ((st -> cnt) < (st -> size)) {
|
|
st -> st[st -> cnt] = val;
|
|
(st -> cnt)++;
|
|
} else {
|
|
fprintf(stderr, "Stack is full! Stack size is %d, value to add is %f\n", st -> size, val);
|
|
}
|
|
}
|
|
|
|
double pop(STACK* st) {
|
|
if ((st -> cnt) > 0) {
|
|
(st -> cnt)--;
|
|
return st -> st[st -> cnt];
|
|
|
|
} else {
|
|
fprintf(stderr, "Attempted to pop an empty stack\n");
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
void add(STACK* st) {
|
|
if ((st -> cnt) > 1) {
|
|
(st -> cnt)--;
|
|
st -> st[(st -> cnt)-1] = st -> st[(st -> cnt)-1] + st -> st[st -> cnt];
|
|
}
|
|
else {
|
|
fprintf(stderr, "Not enough operands to add\n");
|
|
}
|
|
}
|
|
|
|
void substract(STACK* st) {
|
|
if ((st -> cnt) > 1) {
|
|
(st -> cnt)--;
|
|
st -> st[(st -> cnt)-1] = st -> st[(st -> cnt)-1] - st -> st[st -> cnt];
|
|
}
|
|
else {
|
|
fprintf(stderr, "Not enough operands to substract\n");
|
|
}
|
|
}
|
|
|
|
void multiply(STACK* st) {
|
|
if ((st -> cnt) > 1) {
|
|
(st -> cnt)--;
|
|
st -> st[(st -> cnt)-1] = st -> st[(st -> cnt)-1] * st -> st[st -> cnt];
|
|
}
|
|
else {
|
|
fprintf(stderr, "Not enough operands to multiply\n");
|
|
}
|
|
}
|
|
|
|
void divide(STACK* st) {
|
|
if ((st -> cnt) > 1) {
|
|
(st -> cnt)--;
|
|
st -> st[(st -> cnt)-1] = st -> st[(st -> cnt)-1] / st -> st[st -> cnt];
|
|
}
|
|
else {
|
|
fprintf(stderr, "Not enough operands to divide\n");
|
|
}
|
|
}
|
|
|
|
int parse(char *s, STACK* stack) {
|
|
double operand = 0;
|
|
char *endptr;
|
|
if ((*s == '-') && (*(s+1) == '\0')) {
|
|
substract(stack);
|
|
return 0;
|
|
} else if (*s == '+') {
|
|
add(stack);
|
|
return 0;
|
|
} else if (*s == '/') {
|
|
if ((stack -> st[(stack -> cnt)-1]) == 0) {
|
|
return -2;
|
|
}
|
|
divide(stack);
|
|
return 0;
|
|
} else if (*s == 'x') {
|
|
multiply(stack);
|
|
return 0;
|
|
}
|
|
errno = 0;
|
|
operand = strtod(s, &endptr);
|
|
if (errno != 0 || *endptr != '\0') return -1;
|
|
push(stack, operand);
|
|
return 0;
|
|
}
|
|
|
|
|
|
int main(int argc, char **argv) {
|
|
STACK* operands = init_stack(argc);
|
|
if (operands == NULL) {
|
|
fprintf(stderr, "Error creating operand stack.\n");
|
|
return(2);
|
|
}
|
|
int error;
|
|
while(*++argv) {
|
|
error = parse(*argv, operands);
|
|
if (error == -1) {
|
|
fprintf(stderr, "Error parsing operand.\n");
|
|
return(1);
|
|
} else if (error == -2) {
|
|
fprintf(stderr, "Division by zero!");
|
|
return(2);
|
|
}
|
|
}
|
|
int i;
|
|
printf("Stack status:\n");
|
|
for (i = (operands -> cnt); i > 0; i--) printf("%f\n", pop(operands));
|
|
destroy_stack(operands);
|
|
return 0;
|
|
}
|
|
|