[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH v3] pkl,std: add `stof' and `stod'
From: |
Mohammad-Reza Nabipoor |
Subject: |
[PATCH v3] pkl,std: add `stof' and `stod' |
Date: |
Tue, 21 Mar 2023 23:05:32 +0100 |
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);
--
2.39.2
- 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 <=
- Re: [PATCH v3] pkl,std: add `stof' and `stod', Jose E. Marchesi, 2023/03/21
- Re: [PATCH v3] pkl,std: add `stof' and `stod', Mohammad-Reza Nabipoor, 2023/03/22