diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2021-06-24 07:47:48 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2021-06-24 07:47:48 -0700 |
commit | 9ec5e89c859b70b03a65ff773f8f85eddc277f71 (patch) | |
tree | 1b5164d576178af56d9b28fbed3aed3ec54f130f /lib.c | |
parent | c45cb488586b0f8c54120d9eacb6491df017609b (diff) | |
download | txr-9ec5e89c859b70b03a65ff773f8f85eddc277f71.tar.gz txr-9ec5e89c859b70b03a65ff773f8f85eddc277f71.tar.bz2 txr-9ec5e89c859b70b03a65ff773f8f85eddc277f71.zip |
parser: no string allocation when scanning floats.
Each time the scanner processes a floating-point token,
it allocates a string object, just so it can call flo_str.
The object is then garbage. Let's stop doing that.
* lib.c (flo_str_utf8): New function, closely based on flo_str.
Takes a char * string.
* lib.h (flo_str_utf8): Declared.
* parser.l (out_of_range_float): Take the token as a const
char * string instead of a Lisp string, so we can just pass
yytext to this function.
(grammar): Use flo_str_utf8 instead flo_str, and pass yytext
to out_of_range_float.
* lex.yy.c.shipped: Updated.
Diffstat (limited to 'lib.c')
-rw-r--r-- | lib.c | 25 |
1 files changed, 25 insertions, 0 deletions
@@ -5645,6 +5645,31 @@ val int_str(val str, val base) return bignum_from_long(value); } +val flo_str_utf8(const char *str) +{ + char *ptr; + double value; + +#if CONFIG_LOCALE_TOLERANCE + if (dec_point != '.') { + size_t size = strlen(str) + 1; + char *scopy = alloca(size), *dot = scopy; + wmemcpy(scopy, str, size); + str = scopy; + while ((dot = strchr(dot, '.')) != 0) + *dot++ = dec_point; + } +#endif + + value = strtod(str, &ptr); + + if (value == 0 && ptr == str) + return nil; + if ((value == HUGE_VAL || value == -HUGE_VAL) && errno == ERANGE) + return nil; + return flo(value); +} + val flo_str(val str) { val self = lit("flo-str"); |