fixed operator precedence issue
This commit is contained in:
parent
dbd3ff2acd
commit
8e5675a53f
1 changed files with 145 additions and 132 deletions
277
main.c
277
main.c
|
|
@ -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("");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue