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`. --- tests/atlocal.in | 2 +- tests/testsuite.at | 40 +++++++++++++++++++++++++++++----------- 2 files changed, 30 insertions(+), 12 deletions(-) (limited to 'tests') diff --git a/tests/atlocal.in b/tests/atlocal.in index 81dc1fb..8652055 100644 --- a/tests/atlocal.in +++ b/tests/atlocal.in @@ -17,7 +17,7 @@ export SCITECOPATH="@abs_top_srcdir@/lib" # Some test cases may access files from the tests/ source directory. export srcdir -TECO_INTEGER=@TECO_INTEGER@ +TECO_NUMBER=@TECO_NUMBER@ SCITECO_VERSION="@PACKAGE_VERSION@" GREP="@GREP@" diff --git a/tests/testsuite.at b/tests/testsuite.at index 897b4f4..bc5c6da 100644 --- a/tests/testsuite.at +++ b/tests/testsuite.at @@ -49,6 +49,13 @@ TE_CHECK([[23:=]], 0, [23], ignore) TE_CHECK([[1 2= =]], 0, ignore, ignore) TE_CHECK([[033-27"N(0/0)']], 0, ignore, ignore) TE_CHECK([[@0ff-255"N(0/0)']], 0, ignore, ignore) +# floating point numbers +# NOTE: %q does not change the register's number type. +TE_CHECK([[1.Ua 0.1%a:=]], 0, [1.1], ignore) +TE_CHECK([[1Ua 0.1%a:=]], 0, [1], ignore) +TE_CHECK([[23.04:=]], 0, [23.04], ignore) +TE_CHECK([[0.04:=]], 0, [0.04], ignore) +TE_CHECK([[23.04#0:=]], 0, [23], ignore) AT_CLEANUP AT_SETUP([Number stack]) @@ -61,6 +68,8 @@ TE_CHECK([[2%a,%a - 3"N(0/0)' $]], 0, ignore, ignore) # "1,,2" is equivalent to "1,0,2" and (1,) to (1,0). TE_CHECK([[(1,) "~|(0/0)']], 0, ignore, ignore) TE_CHECK([[1,(2)= =]], 0, ignore, ignore) +# commas are optional for pushing several numbers +TE_CHECK([[65 66 67@I// Z-3"N(0/0)']], 0, ignore, ignore) AT_CLEANUP AT_SETUP([Exit status]) @@ -85,6 +94,8 @@ TE_CHECK([[0^*-5=]], 1, ignore, ignore) TE_CHECK([[0^*0 - 1"N(0/0)']], 0, ignore, ignore) TE_CHECK([[1^*-5 - 1"N(0/0)']], 0, ignore, ignore) TE_CHECK([[2^*-5 - 0"N(0/0)']], 0, ignore, ignore) +# floating point numbers +TE_CHECK([[2.^*-5:=]], 0, [0.03125], ignore) AT_CLEANUP AT_SETUP([Missing left operand]) @@ -136,6 +147,9 @@ AT_CLEANUP AT_SETUP([Conditionals]) # FIXME: Add more test cases TE_CHECK([[0"N(0/0)F"]], 0, ignore, ignore) +# floating point numbers +TE_CHECK([[0.1"=(0/0)']], 0, ignore, ignore) +TE_CHECK([[0.1">|(0/0)']], 0, ignore, ignore) AT_CLEANUP AT_SETUP([String arguments]) @@ -183,12 +197,15 @@ m4_define([TE_MININT32], [-2147483648]) m4_define([TE_MAXINT64], [9223372036854775807]) m4_define([TE_MININT64], [-9223372036854775808]) -# TODO: Also check different radixes. AT_SETUP([Formatting numbers]) +TE_CHECK([[16^R @0deadbeaf\ HT]], 0, [deadbeaf], ignore) +TE_CHECK([[^O 0644\ HT]], 0, [644], ignore) +TE_CHECK([[3.141593\ HT]], 0, [3.141593], ignore) +TE_CHECK([[3.0\ HT]], 0, [3], ignore) # MAXINT32/MININT32: should always work. TE_CHECK(TE_MAXINT32[[\ J::@S/]]TE_MAXINT32[[/"F(0/0)']], 0, ignore, ignore) TE_CHECK(TE_MININT32[[\ J::@S/]]TE_MININT32[[/"F(0/0)']], 0, ignore, ignore) -AT_SKIP_IF([test $TECO_INTEGER -lt 64]) +AT_SKIP_IF([test $TECO_NUMBER -lt 64]) TE_CHECK(TE_MAXINT64[[\ J::@S/]]TE_MAXINT64[[/"F(0/0)']], 0, ignore, ignore) TE_CHECK(TE_MININT64[[\ J::@S/]]TE_MININT64[[/"F(0/0)']], 0, ignore, ignore) AT_CLEANUP @@ -199,7 +216,7 @@ AT_CLEANUP AT_SETUP([Integer comparisons]) TE_CHECK([[(]]TE_MAXINT32[[)-(]]TE_MAXINT32[[)"N(0/0)']], 0, ignore, ignore) TE_CHECK([[(]]TE_MININT32[[)-(]]TE_MININT32[[)"N(0/0)']], 0, ignore, ignore) -AT_SKIP_IF([test $TECO_INTEGER -lt 64]) +AT_SKIP_IF([test $TECO_NUMBER -lt 64]) TE_CHECK([[(]]TE_MAXINT64[[)-(]]TE_MAXINT64[[)"N(0/0)']], 0, ignore, ignore) TE_CHECK([[(]]TE_MININT64[[)-(]]TE_MININT64[[)"N(0/0)']], 0, ignore, ignore) AT_CLEANUP @@ -213,17 +230,16 @@ AT_CLEANUP AT_SETUP([Printing numbers]) # Must print only one hexadecimal number. -AT_DATA([expout], [[FF -]]) -TE_CHECK([[255===]], 0, expout, ignore) -# Without LF: No line will be counted. -TE_CHECK([[255:===]], 0, stdout, ignore) -AT_FAIL_IF([test `wc -l ]], 0, expout, ignore) AT_DATA([expout], [[255 @@ -269,6 +285,8 @@ AT_CHECK([[printf "ТЕСТ" | $SCITECO -qe '<^TUa Qa:; Qa=>']], 0, expout, igno # When using --stdin/--stdout, we can rely on the builtin EOL normalization. TE_CHECK([[10^T]], 0, stdout, ignore) TE_CHECK([[16,0ED @EB/stdout/ Z-1"N(0/0)' 0A-10"N(0/0)']], 0, ignore, ignore) +# floats are automatically casted to int +TE_CHECK([[65.5,66.1^T]], 0, [AB], ignore) AT_CLEANUP AT_SETUP([Get character code]) -- cgit v1.2.3