#include "stack.h" #include #include #include void initStack(Stack *s) { s->top = -1; } bool isEmpty(Stack *s) { return s->top == -1; } bool isFull(Stack *s) { return s->top == MAX_STACK_SIZE - 1; } bool push(Stack *s, const char *value, char type) { if (isFull(s)) { fprintf(stderr, "Stack overflow!\n"); return false; } char *new_str = malloc(strlen(value) + 1); if (new_str == NULL) { fprintf(stderr, "Memory allocation failed!\n"); return false; } strcpy(new_str, value); s->top++; s->data[s->top].str_ptr = new_str; s->data[s->top].type = type; return true; } bool pop(Stack *s, Element *out) { if (isEmpty(s)) { fprintf(stderr, "Stack is empty!\n"); return false; } *out = s->data[s->top--]; return true; } bool peek(Stack *s, Element *out) { if (isEmpty(s)) { fprintf(stderr, "Stack is empty!\n"); return false; } *out = s->data[s->top]; return true; } void clearStack(Stack *s) { while (s->top >= 0) { free(s->data[s->top].str_ptr); s->top--; } } char* calulate(Element* tokens, int tokens_count) { #define MAX_ELEMENT_STRING_SIZE 100 Stack s_operands; initStack(&s_operands); for (int i = 0; i < tokens_count; ++i) { Element token = tokens[i]; if (token.type == 'n' || token.type == 'v') { // если число или выражение с переменной - добавляю в стек push(&s_operands, token.str_ptr, token.type); } else { // если оператор char op = token.str_ptr[0]; // беру со стека 2 последних операнда Element second_operand; pop(&s_operands, &second_operand); Element first_operand; pop(&s_operands, &first_operand); char result[MAX_ELEMENT_STRING_SIZE] = { 0 }; if (first_operand.type == 'n' && second_operand.type == 'n') { // оба операнда - числа => вычисляю значение выражения и его закидываю в стек int first_num = atoi(first_operand.str_ptr); int second_num = atoi(second_operand.str_ptr); switch (op) { case '+': { int result_num = first_num + second_num; //printf("%i + %i = %i\n", first_num, second_num, result_num); snprintf(result, MAX_ELEMENT_STRING_SIZE, "%d", result_num); push(&s_operands, result, 'n'); break; } case '-': { int result_num = first_num - second_num; //printf("%i - %i = %i\n", first_num, second_num, result_num); snprintf(result, MAX_ELEMENT_STRING_SIZE, "%d", result_num); push(&s_operands, result, 'n'); break; } case '*': { int result_num = first_num * second_num; //printf("%i * %i = %i\n", first_num, second_num, result_num); snprintf(result, MAX_ELEMENT_STRING_SIZE, "%d", result_num); push(&s_operands, result, 'n'); break; } } } else { // хотя бы один операнд содержит переменную snprintf(result, MAX_ELEMENT_STRING_SIZE, "(%s%c%s)", first_operand.str_ptr, op, second_operand.str_ptr); //printf("%s %c %s = %s\n", first_operand.str_ptr, op, second_operand.str_ptr, result); push(&s_operands, result, 'v'); // Помечаю как выражение с переменной } free(first_operand.str_ptr); free(second_operand.str_ptr); } } if (!isEmpty(&s_operands)) { Element result; pop(&s_operands, &result); //printf("Result: %s\n", result.str_ptr); return result.str_ptr; } return NULL; }