188 lines
4.4 KiB
C
188 lines
4.4 KiB
C
#include <errno.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
|
|
#include "stacks.h"
|
|
|
|
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 sorting_station(STACK *operands, CHAR_STACK *operators, char *token) {
|
|
int error;
|
|
if (((*token == '-') && (*(token + 1) == '\0')) || (*token == '+') ||
|
|
(*token == 'x') || (*token == '/')) {
|
|
if (char_top(operators) != NULL) {
|
|
switch (*char_top(operators)) {
|
|
case '[':
|
|
char_push(operators, *token);
|
|
break;
|
|
case '+':
|
|
case '-':
|
|
if (*token == '/' || *token == 'x') {
|
|
char_push(operators, *token);
|
|
break;
|
|
}
|
|
case 'x':
|
|
case '/':
|
|
if (*token == '/' || *token == 'x') {
|
|
while (char_top(operators) != NULL && (*char_top(operators) == '/' || *char_top(operators) == 'x')) {
|
|
error = parse(char_top(operators), operands);
|
|
if (error != 0) {
|
|
return error;
|
|
}
|
|
char_pop(operators);
|
|
}
|
|
char_push(operators, *token);
|
|
break;
|
|
} else {
|
|
while (char_top(operators) != NULL && *char_top(operators) != '[') {
|
|
error = parse(char_top(operators), operands);
|
|
if (error != 0) {
|
|
return error;
|
|
}
|
|
char_pop(operators);
|
|
}
|
|
char_push(operators, *token);
|
|
break;
|
|
}
|
|
}
|
|
return (0);
|
|
} else {
|
|
char_push(operators, *token);
|
|
return (0);
|
|
}
|
|
}
|
|
|
|
if (*token == '[') {
|
|
char_push(operators, *token);
|
|
return (0);
|
|
}
|
|
|
|
if (*token == ']') {
|
|
while (char_top(operators) != NULL && *char_top(operators) != '[') {
|
|
error = parse(char_top(operators), operands);
|
|
if (error != 0) {
|
|
return error;
|
|
}
|
|
char_pop(operators);
|
|
}
|
|
if (char_top(operators) == NULL) {
|
|
fprintf(stderr, "Opening bracket not found!\n");
|
|
return (-3);
|
|
} else {
|
|
char_pop(operators);
|
|
return (0);
|
|
}
|
|
}
|
|
|
|
error = parse(token, operands);
|
|
return (error);
|
|
}
|
|
|
|
int main(int argc, char **argv) {
|
|
STACK *operands = init_stack(argc);
|
|
CHAR_STACK *operators = init_char_stack(argc);
|
|
|
|
if (operands == NULL) {
|
|
fprintf(stderr, "Error creating operand stack.\n");
|
|
return (2);
|
|
}
|
|
if (operators == NULL) {
|
|
fprintf(stderr, "Error creating operator stack.\n");
|
|
return (2);
|
|
}
|
|
int error;
|
|
while (*++argv) {
|
|
error = sorting_station(operands, operators, *argv);
|
|
if (error == -1) {
|
|
fprintf(stderr, "Error parsing operand.\n");
|
|
return (1);
|
|
} else if (error == -2) {
|
|
fprintf(stderr, "Division by zero!");
|
|
return (2);
|
|
} else if (error == -3) {
|
|
return (3);
|
|
}
|
|
}
|
|
|
|
while (char_top(operators) != NULL) {
|
|
error = parse(char_top(operators), operands);
|
|
if (error == -1) {
|
|
fprintf(stderr, "Error parsing operand.\n");
|
|
return (1);
|
|
} else if (error == -2) {
|
|
fprintf(stderr, "Division by zero!");
|
|
return (2);
|
|
}
|
|
char_pop(operators);
|
|
}
|
|
|
|
int i;
|
|
printf("Stack status:\n");
|
|
for (i = (operands->cnt); i > 0; i--)
|
|
printf("%f\n", pop(operands));
|
|
destroy_stack(operands);
|
|
destroy_char_stack(operators);
|
|
return 0;
|
|
}
|