[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [PATCH v3] pkl,std: add `stof' and `stod'
From: |
Jose E. Marchesi |
Subject: |
Re: [PATCH v3] pkl,std: add `stof' and `stod' |
Date: |
Wed, 22 Mar 2023 04:52:48 +0100 |
User-agent: |
Gnus/5.13 (Gnus v5.13) |
OK for master.
Thanks!
> This commit adds support for conversion from string to float32
> and float64 numbers which are represented as `uint<32>' and
> `uint<64>' integers respectively.
>
> 2023-03-23 Mohammad-Reza Nabipoor <mnabipoor@gnu.org>
>
> * common/pk-utils.h (pvm_stof): New declaration.
> (pvm_stod): Likewise.
> * common/pk-utils.c (pvm_stof): Definition of string to `float'
> conversion function.
> (pvm_stod): Definition of string to `double' conversion function.
> * libpoke/pkl-insn.def (PKL_INSN_STOF): New instruction.
> (PKL_INSN_STOD): Likewise.
> * libpoke/pvm.jitter (wrapped-functions): Add `pvm_stof' and
> `pvm_stod'.
> (stof): New instruction to convert string to float32 number
> represented as a `uint<32>'.
> (stod): New instruction to convert string to float64 number
> represented as a `uint<64>'.
> * libpoke/std.pk (stof): New function to wrap `stof' instruction.
> (stod): Likewise.
> * testsuite/poke.pvm/pvm-insns-test.pk (tests): Add entries for
> `stof' and `stod'.
> * testsuite/poke.std/std-test.pk (tests): Likewise.
> ---
>
> Hi.
>
> Change:
> Add msg to the exceptions.
>
>
> Regards,
> Mohammad-Reza
>
> ChangeLog | 21 +++++++++++
> common/pk-utils.c | 24 ++++++++++++
> common/pk-utils.h | 16 ++++++++
> doc/poke.texi | 26 +++++++++++++
> libpoke/pkl-insn.def | 3 ++
> libpoke/pvm.jitter | 55 ++++++++++++++++++++++++++++
> libpoke/std.pk | 34 +++++++++++++++++
> testsuite/poke.pvm/pvm-insns-test.pk | 45 +++++++++++++++++++++++
> testsuite/poke.std/std-test.pk | 37 +++++++++++++++++++
> 9 files changed, 261 insertions(+)
>
> diff --git a/ChangeLog b/ChangeLog
> index 63e1786a..f7b20a56 100644
> --- a/ChangeLog
> +++ b/ChangeLog
> @@ -1,3 +1,24 @@
> +2023-03-23 Mohammad-Reza Nabipoor <mnabipoor@gnu.org>
> +
> + * common/pk-utils.h (pvm_stof): New declaration.
> + (pvm_stod): Likewise.
> + * common/pk-utils.c (pvm_stof): Definition of string to `float'
> + conversion function.
> + (pvm_stod): Definition of string to `double' conversion function.
> + * libpoke/pkl-insn.def (PKL_INSN_STOF): New instruction.
> + (PKL_INSN_STOD): Likewise.
> + * libpoke/pvm.jitter (wrapped-functions): Add `pvm_stof' and
> + `pvm_stod'.
> + (stof): New instruction to convert string to float32 number
> + represented as a `uint<32>'.
> + (stod): New instruction to convert string to float64 number
> + represented as a `uint<64>'.
> + * libpoke/std.pk (stof): New function to wrap `stof' instruction.
> + (stod): Likewise.
> + * testsuite/poke.pvm/pvm-insns-test.pk (tests): Add entries for
> + `stof' and `stod'.
> + * testsuite/poke.std/std-test.pk (tests): Likewise.
> +
> 2023-03-16 Jose E. Marchesi <jemarch@gnu.org>
>
> * libpoke/pvm.jitter (push32): Fix printers.
> diff --git a/common/pk-utils.c b/common/pk-utils.c
> index f5874d31..1134251c 100644
> --- a/common/pk-utils.c
> +++ b/common/pk-utils.c
> @@ -223,6 +223,30 @@ pk_str_trim (char **str)
> *(end + 1) = '\0';
> }
>
> +int pvm_stof (const char *str, float *f)
> +{
> + char *end;
> +
> + assert (str);
> + assert (f);
> + errno = 0;
> + *f = strtof (str, &end);
> + /* No ERANGE and it should consume the whole string. */
> + return errno != 0 || *end != '\0';
> +}
> +
> +int pvm_stod (const char *str, double *d)
> +{
> + char *end;
> +
> + assert (str);
> + assert (d);
> + errno = 0;
> + *d = strtod (str, &end);
> + /* No ERANGE and it should consume the whole string. */
> + return errno != 0 || *end != '\0';
> +}
> +
> void
> pk_unreachable (const char *funcname, const char *filename, int line)
> {
> diff --git a/common/pk-utils.h b/common/pk-utils.h
> index 37713413..45785574 100644
> --- a/common/pk-utils.h
> +++ b/common/pk-utils.h
> @@ -66,6 +66,22 @@ char *pk_str_replace (const char *in, const char *search,
> const char *replace);
> /* Left and rigth trim the given string from whitespaces. */
> void pk_str_trim (char **str);
>
> +/* Convert floating-point number in input string STR and save the
> + result in *FLT. On conversion error, the function will return a
> + non-zero value.
> +
> + Note that the whole STR should be a valid floating-point number and
> + leading whitespace(s) will be ignored. */
> +int pvm_stof (const char *str, float *flt) __attribute__ ((nonnull));
> +
> +/* Convert floating-point number in input string STR and save the
> + result in *DBL. On conversion error, the function will return a
> + non-zero value.
> +
> + Note that the whole STR should be a valid floating-point number and
> + leading whitespace(s) will be ignored. */
> +int pvm_stod (const char *str, double *dbl) __attribute__ ((nonnull));
> +
> /* This function is called when the program reaches a supposedly
> unreachable point; print an error message and abort the execution.
>
> diff --git a/doc/poke.texi b/doc/poke.texi
> index fcf25a01..b6fcc90c 100644
> --- a/doc/poke.texi
> +++ b/doc/poke.texi
> @@ -15565,6 +15565,8 @@ useful conversions.
> * strtoi:: convert numeric prefix to integer.
> * atoi:: converting strings to integers.
> * ltos:: converting integers to strings.
> +* stof:: converting strings to 32-bit floating-points.
> +* stod:: converting strings to 64-bit floating-points.
> @end menu
>
> @node catos
> @@ -15703,6 +15705,30 @@ fun ltos = (long @var{i}, uint @var{base} = 10)
> string:
> where @var{i} is the number for which to calculate the printed
> representation, and @var{base} is a number between 0 and 16.
>
> +@node stof
> +@subsection @code{stof}
> +@cindex @code{stof}
> +
> +The @code{stof} standard function converts a given string into
> +a 32-bit floating-point number represented as a @code{uint<32>}
> +integer. It has the following prototype:
> +
> +@example
> +fun stof = (string s) uint<32>:
> +@end example
> +
> +@node stod
> +@subsection @code{stod}
> +@cindex @code{stod}
> +
> +The @code{stod} standard function converts a given string into
> +a 64-bit floating-point number represented as a @code{uint<64>}
> +integer. It has the following prototype:
> +
> +@example
> +fun stod = (string s) uint<64>:
> +@end example
> +
> @node Array Functions
> @section Array Functions
> @cindex array functions
> diff --git a/libpoke/pkl-insn.def b/libpoke/pkl-insn.def
> index 36f495c3..94a0a06b 100644
> --- a/libpoke/pkl-insn.def
> +++ b/libpoke/pkl-insn.def
> @@ -105,6 +105,9 @@ PKL_DEF_INSN(PKL_INSN_LUTOIU,"n","lutoiu")
> PKL_DEF_INSN(PKL_INSN_LUTOL,"n","lutol")
> PKL_DEF_INSN(PKL_INSN_LUTOLU,"n","lutolu")
>
> +PKL_DEF_INSN(PKL_INSN_STOF,"","stof")
> +PKL_DEF_INSN(PKL_INSN_STOD,"","stod")
> +
> /* Integer overflow checking instructions. */
>
> PKL_DEF_INSN(PKL_INSN_ADDIOF,"","addiof")
> diff --git a/libpoke/pvm.jitter b/libpoke/pvm.jitter
> index 8b395fa1..d42b69bd 100644
> --- a/libpoke/pvm.jitter
> +++ b/libpoke/pvm.jitter
> @@ -148,6 +148,8 @@ wrapped-functions
> pvm_strcat
> pvm_nanosleep
> pvm_snprintf
> + pvm_stof
> + pvm_stod
> end
>
> wrapped-globals
> @@ -2280,6 +2282,59 @@ instruction formatf64 (?n 0 1 2)
> end
> end
>
> +
> +## Floating-point conversion instructions
> +
> +# Instruction: stof
> +#
> +# Given a string containing only a floating-point number, push the
> +# corresponding 32-bit floating-point number to the stack,
> +# represented as a UINT. On conversion failure, push NULL.
> +#
> +# Note that leading (not trailing) whitespaces will be ignored.
> +#
> +# Stack: ( STR -- UINT )
> +
> +instruction stof ()
> + code
> + union
> + {
> + float f32;
> + uint32_t u32;
> + } u;
> +
> + if (pvm_stof (PVM_VAL_STR (JITTER_TOP_STACK()), &u.f32) == 0)
> + JITTER_TOP_STACK () = PVM_MAKE_UINT (u.u32, 32);
> + else
> + JITTER_TOP_STACK () = PVM_NULL;
> + end
> +end
> +
> +# Instruction: stod
> +#
> +# Given a string containing only a floating-point number, push the
> +# corresponding 64-bit floating-point number to the stack,
> +# represented as a ULONG. On conversion failure, push NULL.
> +#
> +# Note that leading (not trailing) whitespaces will be ignored.
> +#
> +# Stack: ( STR -- ULONG )
> +
> +instruction stod ()
> + code
> + union
> + {
> + double f64;
> + uint64_t u64;
> + } u;
> +
> + if (pvm_stod (PVM_VAL_STR (JITTER_TOP_STACK()), &u.f64) == 0)
> + JITTER_TOP_STACK () = PVM_MAKE_ULONG (u.u64, 64);
> + else
> + JITTER_TOP_STACK () = PVM_NULL;
> + end
> +end
> +
>
> ## Main stack manipulation instructions
>
> diff --git a/libpoke/std.pk b/libpoke/std.pk
> index 8ed331d9..2ffb6c7f 100644
> --- a/libpoke/std.pk
> +++ b/libpoke/std.pk
> @@ -861,3 +861,37 @@ fun pk_vercmp = (any _a, any _b) int<32>:
> diff = cmp (a.offset, b.offset);
> return diff;
> }
> +
> +/* String conversion to 32-bit floating-point number represented
> + as `uint<32>'. */
> +
> +fun stof = (string s) uint<32>:
> +{
> + var f = asm any: ("stof" : s);
> +
> + if (asm int<32>: ("nn; nip" : f))
> + return f as uint<32>;
> + raise Exception {
> + code = EC_conv,
> + name = "conversion error",
> + msg = format ("string '%s' is not a valid floating-point number", s),
> + exit_status = 1,
> + };
> +}
> +
> +/* String conversion to 64-bit floating-point number represented
> + as `uint<64>'. */
> +
> +fun stod = (string s) uint<64>:
> +{
> + var d = asm any: ("stod" : s);
> +
> + if (asm int<32>: ("nn; nip" : d))
> + return d as uint<64>;
> + raise Exception {
> + code = EC_conv,
> + name = "conversion error",
> + msg = format ("string '%s' is not a valid floating-point number", s),
> + exit_status = 1,
> + };
> +}
> diff --git a/testsuite/poke.pvm/pvm-insns-test.pk
> b/testsuite/poke.pvm/pvm-insns-test.pk
> index ac6c759b..db9e4e18 100644
> --- a/testsuite/poke.pvm/pvm-insns-test.pk
> +++ b/testsuite/poke.pvm/pvm-insns-test.pk
> @@ -321,6 +321,51 @@ var tests = [
> assert (u35 isa uint<35> && u35 == 3LU);
> }
> },
> + /* Floating-point instructions. */
> + PkTest {
> + name = "stof",
> + func = lambda (string name) void:
> + {
> + var pi1 = asm any: ("stof" : "3.14159265359");
> +
> + assert (pi1 isa uint<32>);
> + assert (pi1 as uint<32> == 0x40490fdbU);
> +
> + /* Non-OK cases. */
> + assert (asm int<32>: ("stof; nnn; nip" : " "));
> + assert (asm int<32>: ("stof; nnn; nip" : "+"));
> + assert (asm int<32>: ("stof; nnn; nip" : " +"));
> + assert (asm int<32>: ("stof; nnn; nip" : " +1 "));
> + assert (asm int<32>: ("stof; nnn; nip" : "a"));
> +
> + /* OK cases. */
> + assert (asm int<32>: ("stof; nn; nip" : " +1"));
> + assert (asm int<32>: ("stof; nn; nip" : ""));
> + assert (asm int<32>: ("stof; nn; nip" : "-1E9"));
> + }
> + },
> + PkTest {
> + name = "stod",
> + func = lambda (string name) void:
> + {
> + var pi1 = asm any: ("stod" : "3.14159265359");
> +
> + assert (pi1 isa uint<64>);
> + assert (pi1 as uint<64> == 0x400921fb54442eeaUL);
> +
> + /* Non-OK cases. */
> + assert (asm int<32>: ("stod; nnn; nip" : " "));
> + assert (asm int<32>: ("stod; nnn; nip" : "+"));
> + assert (asm int<32>: ("stod; nnn; nip" : " +"));
> + assert (asm int<32>: ("stod; nnn; nip" : " +1 "));
> + assert (asm int<32>: ("stod; nnn; nip" : "a"));
> +
> + /* OK cases. */
> + assert (asm int<32>: ("stod; nn; nip" : " +1"));
> + assert (asm int<32>: ("stod; nn; nip" : ""));
> + assert (asm int<32>: ("stod; nn; nip" : "-1E9"));
> + }
> + },
> ];
>
> var ok = pktest_run (tests);
> diff --git a/testsuite/poke.std/std-test.pk b/testsuite/poke.std/std-test.pk
> index 18c2f869..aa903cc6 100644
> --- a/testsuite/poke.std/std-test.pk
> +++ b/testsuite/poke.std/std-test.pk
> @@ -501,6 +501,43 @@ var tests = [
> assert (pk_version_parse (s).to_string == s);
> },
> },
> + PkTest {
> + name = "string to floating-point conversion",
> + func = lambda (string name) void:
> + {
> + var pi1 = stof ("3.14159265359"),
> + pi2 = stod ("3.14159265359"),
> + pi3 = stof ("+3.1415"),
> + pi4 = stod ("+3.1415");
> +
> + assert (pi1 isa uint<32>);
> + assert (pi1 == 0x40490fdbU);
> +
> + assert (pi2 isa uint<64>);
> + assert (pi2 == 0x400921fb54442eeaUL);
> +
> + assert (pi3 isa uint<32>);
> + assert (pi3 == 0x40490e56U);
> +
> + assert (pi4 isa uint<64>);
> + assert (pi4 == 0x400921cac083126fUL);
> +
> + /* Valid conversions. */
> + assert (!(stof ("") ?! E_conv));
> + assert (!(stof (" 3") ?! E_conv));
> + assert (!(stod ("") ?! E_conv));
> + assert (!(stod (" 3") ?! E_conv));
> + assert (!(stod ("+1e9") ?! E_conv));
> +
> + /* Invalid conversions. */
> + assert (stof (" ") ?! E_conv);
> + assert (stof ("3 ") ?! E_conv);
> + assert (stof ("+ 3") ?! E_conv);
> + assert (stod (" ") ?! E_conv);
> + assert (stod ("3 ") ?! E_conv);
> + assert (stod ("+ 3") ?! E_conv);
> + }
> + },
> ];
>
> exit (pktest_run (tests) ? 0 : 1);
- set floating point, Philippe Marchesseault, 2023/03/11
- Re: set floating point, Mohammad-Reza Nabipoor, 2023/03/13
- [PATCH] pkl,std: add `stof' and `stod', Mohammad-Reza Nabipoor, 2023/03/16
- Re: [PATCH] pkl,std: add `stof' and `stod', Jose E. Marchesi, 2023/03/16
- [PATCH v2] pkl,std: add `stof' and `stod', Mohammad-Reza Nabipoor, 2023/03/21
- Re: [PATCH v2] pkl,std: add `stof' and `stod', Jose E. Marchesi, 2023/03/21
- Re: [PATCH v2] pkl,std: add `stof' and `stod', Mohammad-Reza Nabipoor, 2023/03/21
- Re: [PATCH v2] pkl,std: add `stof' and `stod', Jose E. Marchesi, 2023/03/21
- [PATCH v3] pkl,std: add `stof' and `stod', Mohammad-Reza Nabipoor, 2023/03/21
- Re: [PATCH v3] pkl,std: add `stof' and `stod',
Jose E. Marchesi <=
- Re: [PATCH v3] pkl,std: add `stof' and `stod', Mohammad-Reza Nabipoor, 2023/03/22