diff options
Diffstat (limited to 'src/expressions.c')
-rw-r--r-- | src/expressions.c | 39 |
1 files changed, 31 insertions, 8 deletions
diff --git a/src/expressions.c b/src/expressions.c index 57e2f71..ee6b4dc 100644 --- a/src/expressions.c +++ b/src/expressions.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012-2023 Robin Haberkorn + * Copyright (C) 2012-2024 Robin Haberkorn * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -86,7 +86,7 @@ teco_int_t teco_expressions_pop_num(guint index) { teco_int_t n = 0; - teco_operator_t op = teco_expressions_pop_op(0); + G_GNUC_UNUSED teco_operator_t op = teco_expressions_pop_op(0); g_assert(op == TECO_OP_NUMBER); @@ -114,11 +114,12 @@ teco_expressions_pop_num_calc(teco_int_t *ret, teco_int_t imply, GError **error) } void -teco_expressions_add_digit(gchar digit) +teco_expressions_add_digit(gunichar digit) { teco_int_t n = teco_expressions_args() > 0 ? teco_expressions_pop_num(0) : 0; - teco_expressions_push(n*teco_radix + (n < 0 ? -1 : 1)*(digit - '0')); + /* use g_unichar_digit_value()? */ + teco_expressions_push(n*teco_radix + (n < 0 ? -1 : 1)*((gint)digit - '0')); } void @@ -184,7 +185,28 @@ teco_expressions_calc(GError **error) switch (op) { case TECO_OP_POW: - for (result = 1; vright--; result *= vleft); + if (!vright) { + result = vleft < 0 ? -1 : 1; + break; + } + if (vright < 0) { + if (!vleft) { + g_set_error_literal(error, TECO_ERROR, TECO_ERROR_FAILED, + "Negative power of 0 is not defined"); + return FALSE; + } + result = ABS(vleft) == 1 ? vleft : 0; + break; + } + result = 1; + for (;;) { + if (vright & 1) + result *= vleft; + vright >>= 1; + if (!vright) + break; + vleft *= vleft; + } break; case TECO_OP_MUL: result = vleft * vright; @@ -297,6 +319,9 @@ guint teco_brace_level = 0; void teco_expressions_brace_open(void) { + while (teco_operators->len > 0 && teco_expressions_peek_op(0) == TECO_OP_NEW) + teco_expressions_pop_op(0); + teco_expressions_push_op(TECO_OP_BRACE); teco_undo_guint(teco_brace_level)++; } @@ -374,11 +399,9 @@ teco_expressions_format(gchar *buffer, teco_int_t number) return p; } -#ifndef NDEBUG -static void __attribute__((destructor)) +static void TECO_DEBUG_CLEANUP teco_expressions_cleanup(void) { g_array_free(teco_numbers, TRUE); g_array_free(teco_operators, TRUE); } -#endif |