Patch 8.2.3315

13 views
Skip to first unread message

Bram Moolenaar

unread,
Aug 8, 2021, 9:44:29 AM8/8/21
to vim...@googlegroups.com

Patch 8.2.3315
Problem: Cannot use single quote in a float number for readability.
Solution: Support single quotes like in numbers. (closes #8713)
Files: src/typval.c, src/float.c, src/proto/float.pro, src/json.c,
src/viminfo.c, src/testdir/test_float_func.vim


*** ../vim-8.2.3314/src/typval.c 2021-07-31 19:12:54.100411000 +0200
--- src/typval.c 2021-08-08 15:35:59.098482387 +0200
***************
*** 1704,1709 ****
--- 1704,1710 ----
int want_string UNUSED)
{
int len;
+ int skip_quotes = current_sctx.sc_version >= 4;
#ifdef FEAT_FLOAT
char_u *p;
int get_float = FALSE;
***************
*** 1718,1724 ****
if (**arg == '.')
p = *arg;
else
! p = skipdigits(*arg + 1);
if (!want_string && p[0] == '.' && vim_isdigit(p[1]))
{
get_float = TRUE;
--- 1719,1738 ----
if (**arg == '.')
p = *arg;
else
! {
! p = *arg + 1;
! if (skip_quotes)
! for (;;)
! {
! if (*p == '\'')
! ++p;
! if (!vim_isdigit(*p))
! break;
! p = skipdigits(p);
! }
! else
! p = skipdigits(p);
! }
if (!want_string && p[0] == '.' && vim_isdigit(p[1]))
{
get_float = TRUE;
***************
*** 1740,1746 ****
{
float_T f;

! *arg += string2float(*arg, &f);
if (evaluate)
{
rettv->v_type = VAR_FLOAT;
--- 1754,1760 ----
{
float_T f;

! *arg += string2float(*arg, &f, skip_quotes);
if (evaluate)
{
rettv->v_type = VAR_FLOAT;
***************
*** 1784,1790 ****
varnumber_T n;

// decimal, hex or octal number
! vim_str2nr(*arg, NULL, &len, current_sctx.sc_version >= 4
? STR2NR_NO_OCT + STR2NR_QUOTE
: STR2NR_ALL, &n, NULL, 0, TRUE);
if (len == 0)
--- 1798,1804 ----
varnumber_T n;

// decimal, hex or octal number
! vim_str2nr(*arg, NULL, &len, skip_quotes
? STR2NR_NO_OCT + STR2NR_QUOTE
: STR2NR_ALL, &n, NULL, 0, TRUE);
if (len == 0)
*** ../vim-8.2.3314/src/float.c 2021-07-27 22:00:39.745712396 +0200
--- src/float.c 2021-08-08 15:39:45.437854762 +0200
***************
*** 29,35 ****
int
string2float(
char_u *text,
! float_T *value) // result stored here
{
char *s = (char *)text;
float_T f;
--- 29,36 ----
int
string2float(
char_u *text,
! float_T *value, // result stored here
! int skip_quotes)
{
char *s = (char *)text;
float_T f;
***************
*** 50,55 ****
--- 51,82 ----
*value = NAN;
return 3;
}
+ if (skip_quotes && vim_strchr((char_u *)s, '\'') != NULL)
+ {
+ char_u buf[100];
+ char_u *p = buf;
+ int quotes = 0;
+
+ vim_strncpy(buf, (char_u *)s, 99);
+ p = buf;
+ for (;;)
+ {
+ // remove single quotes between digits, not in the exponent
+ if (*p == '\'')
+ {
+ ++quotes;
+ mch_memmove(p, p + 1, STRLEN(p));
+ }
+ if (!vim_isdigit(*p))
+ break;
+ p = skipdigits(p);
+ }
+ s = (char *)buf;
+ f = strtod(s, &s);
+ *value = f;
+ return (int)((char_u *)s - buf) + quotes;
+ }
+
f = strtod(s, &s);
*value = f;
return (int)((char_u *)s - text);
***************
*** 488,503 ****
{
char_u *p;
int isneg;

if (in_vim9script() && check_for_string_arg(argvars, 0) == FAIL)
return;

p = skipwhite(tv_get_string_strict(&argvars[0]));
isneg = (*p == '-');

if (*p == '+' || *p == '-')
p = skipwhite(p + 1);
! (void)string2float(p, &rettv->vval.v_float);
if (isneg)
rettv->vval.v_float *= -1;
rettv->v_type = VAR_FLOAT;
--- 515,533 ----
{
char_u *p;
int isneg;
+ int skip_quotes;

if (in_vim9script() && check_for_string_arg(argvars, 0) == FAIL)
return;

+ skip_quotes = argvars[1].v_type != VAR_UNKNOWN && tv_get_bool(&argvars[1]);
+
p = skipwhite(tv_get_string_strict(&argvars[0]));
isneg = (*p == '-');

if (*p == '+' || *p == '-')
p = skipwhite(p + 1);
! (void)string2float(p, &rettv->vval.v_float, skip_quotes);
if (isneg)
rettv->vval.v_float *= -1;
rettv->v_type = VAR_FLOAT;
*** ../vim-8.2.3314/src/proto/float.pro 2021-07-04 16:50:50.803781315 +0200
--- src/proto/float.pro 2021-08-08 15:40:02.157808687 +0200
***************
*** 1,5 ****
/* float.c */
! int string2float(char_u *text, float_T *value);
void f_abs(typval_T *argvars, typval_T *rettv);
void f_acos(typval_T *argvars, typval_T *rettv);
void f_asin(typval_T *argvars, typval_T *rettv);
--- 1,5 ----
/* float.c */
! int string2float(char_u *text, float_T *value, int skip_quotes);
void f_abs(typval_T *argvars, typval_T *rettv);
void f_acos(typval_T *argvars, typval_T *rettv);
void f_asin(typval_T *argvars, typval_T *rettv);
*** ../vim-8.2.3314/src/json.c 2021-07-27 22:00:39.745712396 +0200
--- src/json.c 2021-08-08 15:01:55.640512660 +0200
***************
*** 791,802 ****
{
float_T f;

! len = string2float(p, &f);
}
else
{
cur_item->v_type = VAR_FLOAT;
! len = string2float(p, &cur_item->vval.v_float);
}
}
else
--- 791,803 ----
{
float_T f;

! len = string2float(p, &f, FALSE);
}
else
{
cur_item->v_type = VAR_FLOAT;
! len = string2float(p, &cur_item->vval.v_float,
! FALSE);
}
}
else
*** ../vim-8.2.3314/src/viminfo.c 2021-05-07 17:55:51.971584412 +0200
--- src/viminfo.c 2021-08-08 15:02:03.952491057 +0200
***************
*** 1247,1253 ****
(int)(tab - virp->vir_line + 1), TRUE);
#ifdef FEAT_FLOAT
else if (type == VAR_FLOAT)
! (void)string2float(tab + 1, &tv.vval.v_float);
#endif
else
{
--- 1247,1253 ----
(int)(tab - virp->vir_line + 1), TRUE);
#ifdef FEAT_FLOAT
else if (type == VAR_FLOAT)
! (void)string2float(tab + 1, &tv.vval.v_float, FALSE);
#endif
else
{
*** ../vim-8.2.3314/src/testdir/test_float_func.vim 2021-07-27 22:00:39.753712380 +0200
--- src/testdir/test_float_func.vim 2021-08-08 15:41:52.117506482 +0200
***************
*** 239,251 ****
call assert_equal('nan', string(str2float('NaN')))
call assert_equal('nan', string(str2float(' nan ')))

! call assert_equal(1.2, str2float(1.2))
call CheckDefAndScriptFailure2(['str2float(1.2)'], 'E1013: Argument 1: type mismatch, expected string but got float', 'E1174: String required for argument 1')
call assert_fails("call str2float([])", 'E730:')
call assert_fails("call str2float({})", 'E731:')
call assert_fails("call str2float(function('string'))", 'E729:')
endfunc

func Test_float2nr()
call assert_equal(1, float2nr(1.234))
call assert_equal(123, float2nr(1.234e2))
--- 239,266 ----
call assert_equal('nan', string(str2float('NaN')))
call assert_equal('nan', string(str2float(' nan ')))

! call assert_equal('123456.789', string(str2float("123'456.789", 1)))
! call assert_equal('123456.789', string(str2float("12'34'56.789", 1)))
! call assert_equal('123456.789', string(str2float("1'2'3'4'5'6.789", 1)))
! call assert_equal('1.0', string(str2float("1''2.3", 1)))
! call assert_equal('123456.7', string(str2float("123'456.7'89", 1)))
!
! call assert_equal(1.2, str2float(1.2, 0))
call CheckDefAndScriptFailure2(['str2float(1.2)'], 'E1013: Argument 1: type mismatch, expected string but got float', 'E1174: String required for argument 1')
call assert_fails("call str2float([])", 'E730:')
call assert_fails("call str2float({})", 'E731:')
call assert_fails("call str2float(function('string'))", 'E729:')
endfunc

+ def Test_float_quotes()
+ call assert_equal('123456.789', string(123'456.789))
+ call assert_equal('123456.789', string(12'34'56.789))
+ call assert_equal('123456.789', string(1'2'3'4'5'6.789))
+
+ call assert_fails("echo string(1''2.3)", 'E116:')
+ call assert_fails("echo string(123'456.7'89)", 'E116:')
+ enddef
+
func Test_float2nr()
call assert_equal(1, float2nr(1.234))
call assert_equal(123, float2nr(1.234e2))
*** ../vim-8.2.3314/src/version.c 2021-08-08 14:41:48.723930691 +0200
--- src/version.c 2021-08-08 15:42:13.281448474 +0200
***************
*** 757,758 ****
--- 757,760 ----
{ /* Add new patch number below this line */
+ /**/
+ 3315,
/**/

--
Q: How does a UNIX Guru pick up a girl?
A: look; grep; which; eval; nice; uname; talk; date;

/// Bram Moolenaar -- Br...@Moolenaar.net -- http://www.Moolenaar.net \\\
/// \\\
\\\ sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ ///
\\\ help me help AIDS victims -- http://ICCF-Holland.org ///

Dominique Pellé

unread,
Aug 8, 2021, 2:04:46 PM8/8/21
to vim_dev
Bram Moolenaar <Br...@moolenaar.net> wrote:
>
>
> Patch 8.2.3315
> Problem: Cannot use single quote in a float number for readability.
> Solution: Support single quotes like in numbers. (closes #8713)
> Files: src/typval.c, src/float.c, src/proto/float.pro, src/json.c,
> src/viminfo.c, src/testdir/test_float_func.vim

1) Looking at the following page which shows language supporting
digit separators https://rosettacode.org/wiki/Numeric_separator_syntax
the underscore separator appears to be more popular than
the single quote separator. It may also make it simpler for
syntax highlighting as single quotes are used for strings.

Was underscore considered? Vim9 being experimental,
there is still time to change if we want. Anyway, I'm fine
either way.

2) In blobs, we already had a separator which was dot.
as in 0z1234.567. The inconsistency is a bit annoying.

3) what digit separators for integers? Including hex,
binary, octal integers?

Regards
Dominique

Bram Moolenaar

unread,
Aug 8, 2021, 2:17:46 PM8/8/21
to vim...@googlegroups.com, Dominique Pellé

> > Patch 8.2.3315
> > Problem: Cannot use single quote in a float number for readability.
> > Solution: Support single quotes like in numbers. (closes #8713)
> > Files: src/typval.c, src/float.c, src/proto/float.pro, src/json.c,
> > src/viminfo.c, src/testdir/test_float_func.vim
>
> 1) Looking at the following page which shows language supporting
> digit separators https://rosettacode.org/wiki/Numeric_separator_syntax
> the underscore separator appears to be more popular than
> the single quote separator. It may also make it simpler for
> syntax highlighting as single quotes are used for strings.
>
> Was underscore considered? Vim9 being experimental,
> there is still time to change if we want. Anyway, I'm fine
> either way.

I think using underscore for separation is a really bad idea. It's
quite hard to parse, it's too similar to a dot. I know of no locale
supporting it. It's only used in programming languages, afaik. It
became popular because Java supports it. Java has made several bad
choices, thus that's not a good reason to do the same.

The single quote is used in some places, it is very common in
Switzerland (the land of banks). It makes the numbers easy to read.
You can use them without any context, the reader intuitively understands
what it means.

> 2) In blobs, we already had a separator which was dot.
> as in 0z1234.567. The inconsistency is a bit annoying.

We could use the quote in blobs too. I'm actually not sure why we used
the dot, perhaps because in some currencies it is used: 123.456.789,00 euro
is 123456789 euro. But it depends on the locale how dot and comma are
used, which is a hassle in the international internet.

> 3) what digit separators for integers? Including hex,
> binary, octal integers?

Should be able to use single quote too.

--
ARTHUR: You fight with the strength of many men, Sir knight.
I am Arthur, King of the Britons. [pause]
I seek the finest and the bravest knights in the land to join me
in my Court of Camelot. [pause]
You have proved yourself worthy; will you join me? [pause]
You make me sad. So be it. Come, Patsy.
BLACK KNIGHT: None shall pass.
The Quest for the Holy Grail (Monty Python)
Reply all
Reply to author
Forward
0 new messages