From 8e5675a53f815b28ce80ab26171c79b7c918e858 Mon Sep 17 00:00:00 2001 From: Zander Thannhauser Date: Sun, 3 Aug 2025 23:13:33 -0500 Subject: [PATCH] fixed operator precedence issue --- main.c | 277 ++++++++++++++++++++++++++++++--------------------------- 1 file changed, 145 insertions(+), 132 deletions(-) diff --git a/main.c b/main.c index 855a83f..014d282 100644 --- a/main.c +++ b/main.c @@ -766,133 +766,182 @@ struct expression* parse(const char* text) { struct expression* parse_comparision(void) { - struct expression* parse_arithmetic(void) + struct expression* parse_additive(void) { - struct expression* parse_prefix(void) + struct expression* parse_multiplicative(void) { - struct expression* parse_primary(void) + struct expression* parse_prefix(void) { - struct expression* retval; - - switch (tokenkind) + struct expression* parse_primary(void) { - case tk_identifier: + struct expression* retval; + + switch (tokenkind) { - struct string* name = - new_string(buffer.data); + case tk_identifier: + { + struct string* name = + new_string(buffer.data); - retval = new_variable_expression(name); - next_token(); + retval = new_variable_expression(name); + next_token(); - free_string(name); - break; - } + free_string(name); + break; + } - case tk_literal: - { - struct value* value = - scan(buffer.data); + case tk_literal: + { + struct value* value = + scan(buffer.data); - retval = new_literal_expression(value); + retval = new_literal_expression(value); - next_token(); + next_token(); - free_value(value); - break; - } + free_value(value); + break; + } - case tk_oparen: - { - next_token(); - - retval = parse_root(); - - if (tokenkind != tk_cparen) + case tk_oparen: + { + next_token(); + + retval = parse_root(); + + if (tokenkind != tk_cparen) + { + struct string* message = + new_string_from_fmt( + "unexpected '%s'", + tokennames[tokenkind]); + + retval = new_syntax_error_expression(message, retval); + + free_string(message); + } + + next_token(); + break; + } + + default: { struct string* message = new_string_from_fmt( "unexpected '%s'", tokennames[tokenkind]); - retval = new_syntax_error_expression(message, retval); + retval = new_syntax_error_expression(message, NULL); free_string(message); + break; } - - next_token(); - break; } - - default: - { - struct string* message = - new_string_from_fmt( - "unexpected '%s'", - tokennames[tokenkind]); - retval = new_syntax_error_expression(message, NULL); - - free_string(message); - break; - } + return retval; } - return retval; + switch (tokenkind) + { + case tk_emark: + { + next_token(); + + struct expression* sub = + parse_prefix(); + + struct expression* retval = + new_logical_not_expression(sub); + + free_expression(sub); + + return retval; + } + + case tk_plus: + { + next_token(); + + struct expression* sub = + parse_prefix(); + + struct expression* retval = + new_positive_expression(sub); + + free_expression(sub); + + return retval; + } + + case tk_minus: + { + next_token(); + + struct expression* sub = + parse_prefix(); + + struct expression* retval = + new_negative_expression(sub); + + free_expression(sub); + + return retval; + } + + default: + return parse_primary(); + } } - switch (tokenkind) + struct expression* left = parse_prefix(); + + again: switch (tokenkind) { - case tk_emark: + case tk_asterisk: { next_token(); - struct expression* sub = + struct expression* right = parse_prefix(); struct expression* retval = - new_logical_not_expression(sub); + new_binary_expression(ek_multiply, left, right); - free_expression(sub); + free_expression(left); + free_expression(right); - return retval; + left = retval; + + goto again; } - case tk_plus: + case tk_slash: { next_token(); - struct expression* sub = + struct expression* right = parse_prefix(); struct expression* retval = - new_positive_expression(sub); + new_binary_expression(ek_divide, left, right); - free_expression(sub); + free_expression(left); + free_expression(right); - return retval; - } + left = retval; - case tk_minus: - { - next_token(); - - struct expression* sub = - parse_prefix(); - - struct expression* retval = - new_negative_expression(sub); - - free_expression(sub); - - return retval; + goto again; } default: - return parse_primary(); + break; } + + return left; } - struct expression* left = parse_prefix(); + struct expression* left = parse_multiplicative(); again: switch (tokenkind) { @@ -901,7 +950,7 @@ struct expression* parse(const char* text) next_token(); struct expression* right = - parse_prefix(); + parse_multiplicative(); struct expression* retval = new_binary_expression(ek_add, left, right); @@ -919,7 +968,7 @@ struct expression* parse(const char* text) next_token(); struct expression* right = - parse_prefix(); + parse_multiplicative(); struct expression* retval = new_binary_expression(ek_subtract, left, right); @@ -932,42 +981,6 @@ struct expression* parse(const char* text) goto again; } - case tk_asterisk: - { - next_token(); - - struct expression* right = - parse_prefix(); - - struct expression* retval = - new_binary_expression(ek_multiply, left, right); - - free_expression(left); - free_expression(right); - - left = retval; - - goto again; - } - - case tk_slash: - { - next_token(); - - struct expression* right = - parse_prefix(); - - struct expression* retval = - new_binary_expression(ek_divide, left, right); - - free_expression(left); - free_expression(right); - - left = retval; - - goto again; - } - default: break; } @@ -975,7 +988,7 @@ struct expression* parse(const char* text) return left; } - struct expression* left = parse_arithmetic(); + struct expression* left = parse_additive(); again: switch (tokenkind) { @@ -984,7 +997,7 @@ struct expression* parse(const char* text) next_token(); struct expression* right = - parse_arithmetic(); + parse_additive(); struct expression* retval = new_binary_expression(ek_less_than, left, right); @@ -1002,7 +1015,7 @@ struct expression* parse(const char* text) next_token(); struct expression* right = - parse_arithmetic(); + parse_additive(); struct expression* retval = new_binary_expression(ek_less_than_equal_to, left, right); @@ -1020,7 +1033,7 @@ struct expression* parse(const char* text) next_token(); struct expression* right = - parse_arithmetic(); + parse_additive(); struct expression* retval = new_binary_expression(ek_greater_than, left, right); @@ -1038,7 +1051,7 @@ struct expression* parse(const char* text) next_token(); struct expression* right = - parse_arithmetic(); + parse_additive(); struct expression* retval = new_binary_expression(ek_greater_than_equal_to, left, right); @@ -1157,13 +1170,13 @@ struct expression* parse(const char* text) if (tokenkind == tk_qmark) { next_token(); - + struct expression* left = parse_logicals(); - + next_token(); - + struct expression* right = parse_logicals(); - + TODO; } else @@ -1410,7 +1423,7 @@ struct value* evaluate( retval = evaluate(expression->center, scope); break; } - + case ek_negative: { struct value* sub = evaluate(expression->center, scope); @@ -1439,7 +1452,7 @@ struct value* evaluate( free_value(left), free_value(right); break; } - + case ek_greater_than_equal_to: { struct value* left = evaluate(expression->left, scope); @@ -1450,7 +1463,7 @@ struct value* evaluate( free_value(left), free_value(right); break; } - + case ek_less_than: { struct value* left = evaluate(expression->left, scope); @@ -1461,7 +1474,7 @@ struct value* evaluate( free_value(left), free_value(right); break; } - + case ek_less_than_equal_to: { struct value* left = evaluate(expression->left, scope); @@ -1483,7 +1496,7 @@ struct value* evaluate( free_value(left), free_value(right); break; } - + case ek_not_equal_to: { struct value* left = evaluate(expression->left, scope); @@ -1504,7 +1517,7 @@ struct value* evaluate( free_value(sub); break; } - + case ek_logical_and: { struct value* left = evaluate(expression->left, scope); @@ -1516,7 +1529,7 @@ struct value* evaluate( free_value(left), free_value(right); break; } - + case ek_logical_or: { struct value* left = evaluate(expression->left, scope); @@ -1558,7 +1571,7 @@ struct value* evaluate( void print_mpz(const mpz_t x_ro, const char* digits[10]) { assert(mpz_sgn(x_ro) > 0); - + mpz_t x, d, b; mpz_init(x), mpz_init(d), mpz_init(b); @@ -1584,7 +1597,7 @@ void print_mpz(const mpz_t x_ro, const char* digits[10]) *moving++ = diu; } - + while (moving > buffer) { printf("%s", digits[*--moving]); @@ -1615,7 +1628,7 @@ void print(struct value* this) mpq_abs(v, v); } - + mpz_t q; mpz_init(q); @@ -1655,7 +1668,7 @@ void print(struct value* this) } mpq_clear(v); - + puts(""); }