fixed operator precedence issue

This commit is contained in:
Zander Thannhauser 2025-08-03 23:13:33 -05:00
parent dbd3ff2acd
commit 8e5675a53f

277
main.c
View file

@ -766,133 +766,182 @@ struct expression* parse(const char* text)
{ {
struct expression* parse_comparision(void) 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; struct expression* parse_primary(void)
switch (tokenkind)
{ {
case tk_identifier: struct expression* retval;
switch (tokenkind)
{ {
struct string* name = case tk_identifier:
new_string(buffer.data); {
struct string* name =
new_string(buffer.data);
retval = new_variable_expression(name); retval = new_variable_expression(name);
next_token(); next_token();
free_string(name); free_string(name);
break; break;
} }
case tk_literal: case tk_literal:
{ {
struct value* value = struct value* value =
scan(buffer.data); scan(buffer.data);
retval = new_literal_expression(value); retval = new_literal_expression(value);
next_token(); next_token();
free_value(value); free_value(value);
break; break;
} }
case tk_oparen: case tk_oparen:
{ {
next_token(); next_token();
retval = parse_root(); retval = parse_root();
if (tokenkind != tk_cparen) 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 = struct string* message =
new_string_from_fmt( new_string_from_fmt(
"unexpected '%s'", "unexpected '%s'",
tokennames[tokenkind]); tokennames[tokenkind]);
retval = new_syntax_error_expression(message, retval); retval = new_syntax_error_expression(message, NULL);
free_string(message); 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); return retval;
free_string(message);
break;
}
} }
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(); next_token();
struct expression* sub = struct expression* right =
parse_prefix(); parse_prefix();
struct expression* retval = 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(); next_token();
struct expression* sub = struct expression* right =
parse_prefix(); parse_prefix();
struct expression* retval = 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: goto again;
{
next_token();
struct expression* sub =
parse_prefix();
struct expression* retval =
new_negative_expression(sub);
free_expression(sub);
return retval;
} }
default: default:
return parse_primary(); break;
} }
return left;
} }
struct expression* left = parse_prefix(); struct expression* left = parse_multiplicative();
again: switch (tokenkind) again: switch (tokenkind)
{ {
@ -901,7 +950,7 @@ struct expression* parse(const char* text)
next_token(); next_token();
struct expression* right = struct expression* right =
parse_prefix(); parse_multiplicative();
struct expression* retval = struct expression* retval =
new_binary_expression(ek_add, left, right); new_binary_expression(ek_add, left, right);
@ -919,7 +968,7 @@ struct expression* parse(const char* text)
next_token(); next_token();
struct expression* right = struct expression* right =
parse_prefix(); parse_multiplicative();
struct expression* retval = struct expression* retval =
new_binary_expression(ek_subtract, left, right); new_binary_expression(ek_subtract, left, right);
@ -932,42 +981,6 @@ struct expression* parse(const char* text)
goto again; 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: default:
break; break;
} }
@ -975,7 +988,7 @@ struct expression* parse(const char* text)
return left; return left;
} }
struct expression* left = parse_arithmetic(); struct expression* left = parse_additive();
again: switch (tokenkind) again: switch (tokenkind)
{ {
@ -984,7 +997,7 @@ struct expression* parse(const char* text)
next_token(); next_token();
struct expression* right = struct expression* right =
parse_arithmetic(); parse_additive();
struct expression* retval = struct expression* retval =
new_binary_expression(ek_less_than, left, right); new_binary_expression(ek_less_than, left, right);
@ -1002,7 +1015,7 @@ struct expression* parse(const char* text)
next_token(); next_token();
struct expression* right = struct expression* right =
parse_arithmetic(); parse_additive();
struct expression* retval = struct expression* retval =
new_binary_expression(ek_less_than_equal_to, left, right); new_binary_expression(ek_less_than_equal_to, left, right);
@ -1020,7 +1033,7 @@ struct expression* parse(const char* text)
next_token(); next_token();
struct expression* right = struct expression* right =
parse_arithmetic(); parse_additive();
struct expression* retval = struct expression* retval =
new_binary_expression(ek_greater_than, left, right); new_binary_expression(ek_greater_than, left, right);
@ -1038,7 +1051,7 @@ struct expression* parse(const char* text)
next_token(); next_token();
struct expression* right = struct expression* right =
parse_arithmetic(); parse_additive();
struct expression* retval = struct expression* retval =
new_binary_expression(ek_greater_than_equal_to, left, right); new_binary_expression(ek_greater_than_equal_to, left, right);
@ -1157,13 +1170,13 @@ struct expression* parse(const char* text)
if (tokenkind == tk_qmark) if (tokenkind == tk_qmark)
{ {
next_token(); next_token();
struct expression* left = parse_logicals(); struct expression* left = parse_logicals();
next_token(); next_token();
struct expression* right = parse_logicals(); struct expression* right = parse_logicals();
TODO; TODO;
} }
else else
@ -1410,7 +1423,7 @@ struct value* evaluate(
retval = evaluate(expression->center, scope); retval = evaluate(expression->center, scope);
break; break;
} }
case ek_negative: case ek_negative:
{ {
struct value* sub = evaluate(expression->center, scope); struct value* sub = evaluate(expression->center, scope);
@ -1439,7 +1452,7 @@ struct value* evaluate(
free_value(left), free_value(right); free_value(left), free_value(right);
break; break;
} }
case ek_greater_than_equal_to: case ek_greater_than_equal_to:
{ {
struct value* left = evaluate(expression->left, scope); struct value* left = evaluate(expression->left, scope);
@ -1450,7 +1463,7 @@ struct value* evaluate(
free_value(left), free_value(right); free_value(left), free_value(right);
break; break;
} }
case ek_less_than: case ek_less_than:
{ {
struct value* left = evaluate(expression->left, scope); struct value* left = evaluate(expression->left, scope);
@ -1461,7 +1474,7 @@ struct value* evaluate(
free_value(left), free_value(right); free_value(left), free_value(right);
break; break;
} }
case ek_less_than_equal_to: case ek_less_than_equal_to:
{ {
struct value* left = evaluate(expression->left, scope); struct value* left = evaluate(expression->left, scope);
@ -1483,7 +1496,7 @@ struct value* evaluate(
free_value(left), free_value(right); free_value(left), free_value(right);
break; break;
} }
case ek_not_equal_to: case ek_not_equal_to:
{ {
struct value* left = evaluate(expression->left, scope); struct value* left = evaluate(expression->left, scope);
@ -1504,7 +1517,7 @@ struct value* evaluate(
free_value(sub); free_value(sub);
break; break;
} }
case ek_logical_and: case ek_logical_and:
{ {
struct value* left = evaluate(expression->left, scope); struct value* left = evaluate(expression->left, scope);
@ -1516,7 +1529,7 @@ struct value* evaluate(
free_value(left), free_value(right); free_value(left), free_value(right);
break; break;
} }
case ek_logical_or: case ek_logical_or:
{ {
struct value* left = evaluate(expression->left, scope); 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]) void print_mpz(const mpz_t x_ro, const char* digits[10])
{ {
assert(mpz_sgn(x_ro) > 0); assert(mpz_sgn(x_ro) > 0);
mpz_t x, d, b; mpz_t x, d, b;
mpz_init(x), mpz_init(d), mpz_init(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; *moving++ = diu;
} }
while (moving > buffer) while (moving > buffer)
{ {
printf("%s", digits[*--moving]); printf("%s", digits[*--moving]);
@ -1615,7 +1628,7 @@ void print(struct value* this)
mpq_abs(v, v); mpq_abs(v, v);
} }
mpz_t q; mpz_t q;
mpz_init(q); mpz_init(q);
@ -1655,7 +1668,7 @@ void print(struct value* this)
} }
mpq_clear(v); mpq_clear(v);
puts(""); puts("");
} }