diff options
Diffstat (limited to 'src/expressions.h')
| -rw-r--r-- | src/expressions.h | 76 |
1 files changed, 65 insertions, 11 deletions
diff --git a/src/expressions.h b/src/expressions.h index 37aef70..1c1b4e9 100644 --- a/src/expressions.h +++ b/src/expressions.h @@ -79,7 +79,8 @@ typedef enum { TECO_OP_NIL = 0x00, TECO_OP_NEW, TECO_OP_BRACE, - TECO_OP_NUMBER, + TECO_OP_INTEGER, + TECO_OP_FLOAT, /* * Real operators */ @@ -102,7 +103,23 @@ teco_set_num_sign(gint sign) teco_undo_gint(teco_num_sign) = sign; } -void teco_expressions_push_int(teco_int_t number); +teco_operator_t teco_expressions_peek_op(guint index); +teco_operator_t teco_expressions_pop_op(guint index); +void teco_expressions_push_op(teco_operator_t op); + +void teco_expressions_push_num(teco_number_t number, gboolean is_float); + +static inline void +teco_expressions_push_int(teco_int_t number) +{ + teco_expressions_push_num((teco_number_t){.i = number}, FALSE); +} + +static inline void +teco_expressions_push_float(teco_float_t number) +{ + teco_expressions_push_num((teco_number_t){.f = number}, TRUE); +} /** Push characters of a C-string. */ static inline void @@ -112,11 +129,46 @@ teco_expressions_push_str(const gchar *str) teco_expressions_push_int(*str++); } -teco_int_t teco_expressions_peek_num(guint index); -teco_int_t teco_expressions_pop_num(guint index); -gboolean teco_expressions_pop_num_calc(teco_int_t *ret, teco_int_t imply, GError **error); +teco_number_t teco_expressions_peek_num(guint index); + +static inline teco_int_t +teco_expressions_peek_int(guint index) +{ + teco_number_t number = teco_expressions_peek_num(index); + return teco_expressions_peek_op(index) == TECO_OP_FLOAT ? (teco_int_t)number.f : number.i; +} + +teco_number_t teco_expressions_pop_num(guint index, gboolean *is_float); + +static inline teco_int_t +teco_expressions_pop_int(guint index) +{ + gboolean is_float; + teco_number_t number = teco_expressions_pop_num(index, &is_float); + return is_float ? (teco_int_t)number.f : number.i; +} + +gboolean teco_expressions_pop_num_calc(teco_number_t *ret, gboolean *is_float, + teco_int_t imply, GError **error); + +/** + * Pop an integer from the number stack. + * + * This automatically casts floats to integers. + * + * @see teco_expressions_pop_num_calc + */ +static inline gboolean +teco_expressions_pop_int_calc(teco_int_t *ret, teco_int_t imply, GError **error) +{ + teco_number_t number; + gboolean is_float; + if (!teco_expressions_pop_num_calc(&number, &is_float, imply, error)) + return FALSE; + *ret = is_float ? (teco_int_t)number.f : number.i; + return TRUE; +} -void teco_expressions_push_op(teco_operator_t op); gboolean teco_expressions_push_calc(teco_operator_t op, GError **error); /* @@ -124,12 +176,10 @@ gboolean teco_expressions_push_calc(teco_operator_t op, GError **error); */ #define teco_expressions_push(X) \ (_Generic((X), default : teco_expressions_push_int, \ + teco_float_t : teco_expressions_push_float, \ char * : teco_expressions_push_str, \ const char * : teco_expressions_push_str)(X)) -teco_operator_t teco_expressions_peek_op(guint index); -teco_operator_t teco_expressions_pop_op(guint index); - gboolean teco_expressions_eval(gboolean pop_brace, GError **error); guint teco_expressions_args(void); @@ -146,8 +196,12 @@ gboolean teco_expressions_brace_close(GError **error); void teco_expressions_clear(void); -/** Maximum size required to format a number if radix == 2 */ +/** + * Maximum size required to format a teco_int_t if radix == 2. + * It's also sufficient for formatting a teco_float_t. + */ #define TECO_EXPRESSIONS_FORMAT_LEN \ (1 + sizeof(teco_int_t)*8 + 1) -gchar *teco_expressions_format(gchar *buffer, teco_int_t number, teco_qreg_t *radix); +gchar *teco_expressions_format_int(gchar *buffer, teco_int_t number, teco_qreg_t *radix); +gchar *teco_expressions_format_float(gchar *buffer, teco_float_t number, guint precision); |
