aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/expressions.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/expressions.h')
-rw-r--r--src/expressions.h76
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);