From 4aa2b717f9e050783b567540d9bb0193d692e3e9 Mon Sep 17 00:00:00 2001 From: Robin Haberkorn Date: Sat, 31 Oct 2026 13:46:11 +0100 Subject: 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`. --- src/sciteco.h | 44 +++++++++++++++++++++++++++++++++++++------- 1 file changed, 37 insertions(+), 7 deletions(-) (limited to 'src/sciteco.h') diff --git a/src/sciteco.h b/src/sciteco.h index 88078c2..9d34d50 100644 --- a/src/sciteco.h +++ b/src/sciteco.h @@ -23,18 +23,48 @@ #include -#if TECO_INTEGER == 32 +#if TECO_NUMBER == 32 + typedef gint32 teco_int_t; -#define TECO_INT_MODIFIER G_GINT32_MODIFIER -#define TECO_INT_FORMAT G_GINT32_FORMAT -#elif TECO_INTEGER == 64 +#define TECO_INT_MODIFIER G_GINT32_MODIFIER +#define TECO_INT_FORMAT G_GINT32_FORMAT + +typedef gfloat teco_float_t; +#define TECO_FLOAT_MODIFIER "" +#define TECO_FLOAT_FORMAT "g" + +#elif TECO_NUMBER == 64 + typedef gint64 teco_int_t; -#define TECO_INT_MODIFIER G_GINT64_MODIFIER -#define TECO_INT_FORMAT G_GINT64_FORMAT +#define TECO_INT_MODIFIER G_GINT64_MODIFIER +#define TECO_INT_FORMAT G_GINT64_FORMAT + +typedef gdouble teco_float_t; +#define TECO_FLOAT_MODIFIER "l" +#define TECO_FLOAT_FORMAT "lg" + #else -#error Invalid TECO integer storage size + +#error Invalid TECO number storage size + #endif +/** + * A number cell - either integer or float. + * The tagging is stored outside (either in + * a flag or on the operator stack). + */ +typedef union { + teco_int_t i; + teco_float_t f; +} teco_number_t; + +/* + * FIXME: The storage size of float and double are not guaranteed + * to be 32-bit and 64-bit. + */ +//G_STATIC_ASSERT(sizeof(teco_number_t) == sizeof(teco_int_t)); + /** * A TECO boolean - this differs from C booleans. * See teco_is_success()/teco_is_failure(). -- cgit v1.2.3