diff --git a/main.c b/main.c index a6a3f47..5b46a9c 100644 --- a/main.c +++ b/main.c @@ -23,7 +23,7 @@ bool stack_higher_precedence(char op, char stackOp); stack split_into_tokens(string expression); -string get_slice(int a, size_t b, const char *expression); +string get_slice(int a, int b, const char *expression); bool validate_expression(const char *expression); @@ -33,14 +33,12 @@ void validate_malloc(const void *p); void throw_error(char *msg); -const char *OPERATORS[] = {"+-", "*/", "^", "()"}; - int main(const int argc, char *argv[]) { const string expression = get_expression(argc, argv); if (expression.string == nullptr) return 0; stack tokens = split_into_tokens(expression); - stack_print(&tokens, "Tokens"); + stack_print(&tokens, "tokens"); stack output_queue = get_output_queue(&tokens); @@ -56,7 +54,7 @@ int main(const int argc, char *argv[]) { int calculate_stack(const stack *output_queue) { stack calculation_stack = stack_init(IntArray, output_queue->len); - for (size_t i = 0; i <= output_queue->i; i++) { + for (int i = 0; i <= output_queue->i; i++) { const stackData element = stack_get(output_queue, i); if (element.ret_code == 1) throw_error("Couldn't retrieve element from output queue for calculation stack push"); @@ -106,7 +104,8 @@ int str_to_num(char *string) { // ReSharper disable once CppNotAllPathsReturnValue int calculate(const int a, const int b, const char op) { - switch (op) { + // ReSharper disable once CppDefaultCaseNotHandledInSwitchStatement + switch (op) { // NOLINT(*-multiway-paths-covered) case '+': return a + b; case '-': @@ -157,7 +156,7 @@ stack get_output_queue(const stack *tokenisedExpression) { stack output_stack = stack_init(StringArray, tokenisedExpression->len); stack operator_stack = stack_init(CharArray, tokenisedExpression->len); - for (size_t i = 0; i < tokenisedExpression->i; i++) { + for (size_t i = 0; i <= tokenisedExpression->i; i++) { const stackData token = stack_get(tokenisedExpression, i); if (token.ret_code == 1) throw_error("Failed to retrieve token"); @@ -216,19 +215,24 @@ int push_operator(const char operatorToPush, stack *output_stack, stack *operato } bool stack_higher_precedence(const char op, const char stackOp) { - return validate_char(stackOp).opPrecedence > validate_char(op).opPrecedence; + const int stackOpPrecedence = validate_char(stackOp).opPrecedence, opPrecedence = validate_char(op).opPrecedence; + if (stackOpPrecedence == -1 || opPrecedence == -1) return false; + + return stackOpPrecedence > opPrecedence; } stack split_into_tokens(const string expression) { stack tokenisedExpression = stack_init(StringArray, expression.len); int lastOp = -1; - for (size_t i = 0; i < expression.len; i++) { + // -1 is to not push \0 onto stack + for (size_t i = 0; i < expression.len - 1; i++) { if (validate_char(expression.string[i]).type != Operator) continue; const string slice = get_slice(lastOp, i, expression.string); if (slice.string != nullptr) { const int ret = stack_push(&tokenisedExpression, (stackInput){.string = slice.string}, false); + free(slice.string); if (ret == 1) throw_error("Failed to push slice into stack"); } @@ -241,19 +245,17 @@ stack split_into_tokens(const string expression) { return tokenisedExpression; } -// todo fix edge case on beginning -string get_slice(int a, size_t b, const char *expression) { - const size_t len = b - abs(a) - 1; +string get_slice(int a, int b, const char *expression) { + const int len = b - a - 1; if (len < 1) return (string){.string = nullptr}; - const size_t total_len = len * sizeof(char) + 1; + const int total_len = len * sizeof(char) + 1; char *slice = malloc(total_len); validate_malloc(slice); - for (const size_t i = ++a; a < b; a++) { - // we don't track i separately but how much has a moved since we started creating the slice + // we don't track i separately but how much has 'a' moved since we started creating the slice slice[a - i] = expression[a]; } @@ -270,11 +272,13 @@ bool validate_expression(const char *expression) { charResult validate_char(const char c) { if (isdigit(c)) return (charResult){Digit, 0}; + const char *OPERATORS[] = {"+-", "*/", "^", "()"}; for (int i = 0; i < sizeof(OPERATORS); i++) { for (int j = 0; j < sizeof(OPERATORS[i]); j++) { if (c == OPERATORS[i][j]) - return (charResult){Operator, i}; + // if the operators are parenthesis return 'invalid' precedence + return (charResult){Operator, i == sizeof(OPERATORS) - 1 ? -1 : i}; } } diff --git a/stack.c b/stack.c index 57f304b..facc5ef 100644 --- a/stack.c +++ b/stack.c @@ -15,17 +15,17 @@ stack stack_init(const DataType type, const int len) { .len = len, }; - const size_t arrLen = len * sizeof(char); + const size_t arrLen = len; switch (type) { case StringArray: - stack.data.sarr = malloc(arrLen); + stack.data.sarr = malloc(arrLen * sizeof(char *)); break; case CharArray: - stack.data.carr = malloc(arrLen); + stack.data.carr = malloc(arrLen * sizeof(char)); break; case IntArray: - stack.data.narr = malloc(arrLen); + stack.data.narr = malloc(arrLen * sizeof(int)); default: fprintf(stderr, "Failed to recognise the DataType for Stack structure"); exit(1); @@ -106,18 +106,21 @@ stackData stack_pop(stack *stack) { } stackData stack_get(const stack *stack, const int n) { - if (stack->i == -1 || n >= stack->len) return (stackData){.ret_code = 1}; + if (stack->i == -1 || n > stack->i) return (stackData){.ret_code = 1}; stackInput returnData; switch (stack->type) { case StringArray: - returnData.string = stack->data.sarr[stack->i]; + // todo do not forget to think about freeing memory + const size_t len = strlen(stack->data.sarr[n]); + returnData.string = malloc(len * sizeof(char) + 1); + strcpy(returnData.string, stack->data.sarr[n]); break; case CharArray: - returnData.ch = stack->data.carr[stack->i]; + returnData.ch = stack->data.carr[n]; break; case IntArray: - returnData.n = stack->data.narr[stack->i]; + returnData.n = stack->data.narr[n]; break; } @@ -151,7 +154,7 @@ void stack_print(const stack *stack, const char *name) { printf("\n"); } - printf("\n"); + printf("i location: %d\n", stack->i); } static void clear_str_array(const stack *stack) { diff --git a/stack.h b/stack.h index 9803969..7cd92cf 100644 --- a/stack.h +++ b/stack.h @@ -21,6 +21,7 @@ typedef struct { } data; // if i >= len, the program's guardrails have failed + // i represents last written array space, len represents the array's length int i, len; } stack; diff --git a/structures.h b/structures.h index 07454a4..13d46a0 100644 --- a/structures.h +++ b/structures.h @@ -13,7 +13,7 @@ typedef enum { typedef struct { charType type; - size_t opPrecedence; + int opPrecedence; } charResult; typedef struct {