diff options
| author | Robin Haberkorn <rhaberkorn@fmsbw.de> | 2026-10-31 13:46:11 +0100 |
|---|---|---|
| committer | Robin Haberkorn <rhaberkorn@fmsbw.de> | 2026-10-31 21:13:19 +0100 |
| commit | 4aa2b717f9e050783b567540d9bb0193d692e3e9 (patch) | |
| tree | 39b3734c464655e6d1c21390945209a66f952654 /src/qreg.h | |
| parent | e0bf13622b0922252439e3fa8b43df9877678d75 (diff) | |
support floating point numbers
* Extends the SciTECO type system. A number on the expression stack
or in a Q-register can be either an integer or a float.
* Floating point constants begin with a digit (like all other
numbers), are followed by a `.` and an optional fractional part.
Exponents cannot currently be written.
E.g. `1.` == `1.0`. But `.0` would still be `.,0`.
(!) To push an integer followed by dot, you must now write e.g. `1,.` or `1 .`.
* All of the basic arithmetic operators operate like this:
If both operands are integers, the result is also an integer (integer arithmetics).
If at least one of the operands is a float, the result is also a float (float arithmetics).
* All of the binary operators (AND, OR, XOR) always cast all
operands to integer and the result is always an integer as well.
* You can "cast" integers to float by `*1.` or `/1.`.
You can "cast" floats to integers using `#0`.
* Most commands still accept only integers. Floats are implicitly casted to integers.
Float-aware commands are: =, \, ^W, Qq, Uq, %q and the conditionals.
* `%q` will not change the current type of register q.
* Numeric part of "lexer.font" is now a float (in points).
* You cannot currently print octal and hexadecimal floats.
`==` and `===` are identical to `=` on floats.
* `===` is now printing hex integers in lower case.
This is because SciTECO's coding style for hex constants is also lower case.
* `--with-teco-integer` renamed to `--with-teco-number`.
Diffstat (limited to 'src/qreg.h')
| -rw-r--r-- | src/qreg.h | 68 |
1 files changed, 48 insertions, 20 deletions
@@ -54,9 +54,15 @@ extern teco_view_t *teco_qreg_view; * FIXME: We can probably get rid of all the separate undo callbacks/methods. */ typedef const struct { + /* + * FIXME: perhaps there should only be a set_number() callback with some + * teco_qreg_set_integer() shortcut. + */ /* already pushes undo tokens */ - gboolean (*set_integer)(teco_qreg_t *qreg, teco_int_t value, GError **error); - gboolean (*get_integer)(teco_qreg_t *qreg, teco_int_t *ret, GError **error); + gboolean (*set_number)(teco_qreg_t *qreg, teco_number_t value, + gboolean is_float, GError **error); + gboolean (*get_number)(teco_qreg_t *qreg, teco_number_t *ret, + gboolean *is_float, GError **error); gboolean (*set_string)(teco_qreg_t *qreg, const gchar *str, gsize len, guint codepage, GError **error); @@ -100,26 +106,48 @@ struct teco_qreg_t { teco_qreg_vtable_t *vtable; - teco_int_t integer; + teco_number_t number; teco_doc_t string; - /** - * Whether to generate undo tokens (unnecessary for registers - * in local qreg tables in macro invocations). - * - * @fixme Every QRegister has this field, but it only differs - * between local and global QRegisters. This wastes space. - * Or by deferring any decision about undo token creation to a layer - * that knows which table it is accessing. - * On the other hand, we will need another flag like - * teco_qreg_current_must_undo. - * - * Otherwise, it might be possible to use a least significant bit - * in one of the pointers... - */ - gboolean must_undo; + struct teco_qreg_flags_t { + /** + * Whether to generate undo tokens (unnecessary for registers + * in local qreg tables in macro invocations). + * + * @fixme Every QRegister has this field, but it only differs + * between local and global QRegisters. This wastes space. + * Or by deferring any decision about undo token creation to a layer + * that knows which table it is accessing. + * On the other hand, we will need another flag like + * teco_qreg_current_must_undo. + * + * Otherwise, it might be possible to use a least significant bit + * in one of the pointers... + */ + guint must_undo : 1; + /** whether the number cell is integer or float_val */ + guint is_float : 1; + } flags; }; +static inline gboolean +teco_qreg_set_integer(teco_qreg_t *qreg, teco_int_t value, GError **error) +{ + return qreg->vtable->set_number(qreg, (teco_number_t){.i = value}, FALSE, error); +} + +static inline gboolean +teco_qreg_get_integer(teco_qreg_t *qreg, teco_int_t *ret, GError **error) +{ + teco_number_t number; + gboolean is_float; + + if (!qreg->vtable->get_number(qreg, &number, &is_float, error)) + return FALSE; + *ret = is_float ? (teco_int_t)number.f : number.i; + return TRUE; +} + teco_qreg_t *teco_qreg_plain_new(const gchar *name, gsize len); teco_qreg_t *teco_qreg_dot_new(void); teco_qreg_t *teco_qreg_bufferinfo_new(void); @@ -175,7 +203,7 @@ void teco_qreg_table_init_locals(teco_qreg_table_t *table, gboolean must_undo); static inline teco_qreg_t * teco_qreg_table_insert(teco_qreg_table_t *table, teco_qreg_t *qreg) { - qreg->must_undo = table->must_undo; // FIXME + qreg->flags.must_undo = table->must_undo; // FIXME return (teco_qreg_t *)teco_rb3str_insert(&table->tree, TRUE, &qreg->head); } @@ -242,7 +270,7 @@ teco_qreg_table_get_integer(teco_qreg_table_t *table, const gchar *name, return FALSE; } - return reg->vtable->get_integer(reg, ret, error); + return teco_qreg_get_integer(reg, ret, error); } teco_qreg_t *teco_qreg_table_edit_name(teco_qreg_table_t *table, const gchar *name, |
