diff --git a/vlib/builtin/int_test.v b/vlib/builtin/int_test.v index 793986ae3b..f22d0b4ef7 100644 --- a/vlib/builtin/int_test.v +++ b/vlib/builtin/int_test.v @@ -148,21 +148,18 @@ fn test_num_separator() { // int assert 100_000_0 == 1000000 assert -2_23_4_6 == -22346 - assert 230_ == 230 // bin assert 0b0_11 == 3 assert -0b0_100 == -4 - assert 0b010_ == 2 // oct assert 0o1_73 == 123 assert -0o17_5 == -125 - assert -0o175_ == -125 + assert -0o175 == -125 // hex assert 0xFF == 255 - assert 0xFF_ == 255 assert 0xF_F == 255 // f32 or f64 diff --git a/vlib/v/scanner/scanner.v b/vlib/v/scanner/scanner.v index 607180b95b..f36ef8c02f 100644 --- a/vlib/v/scanner/scanner.v +++ b/vlib/v/scanner/scanner.v @@ -338,6 +338,9 @@ fn (mut s Scanner) ident_bin_number() string { } for s.pos < s.text.len { c := s.text[s.pos] + if c == num_sep && s.text[s.pos + 1] == num_sep { + s.error('cannot use `_` consecutively') + } if !c.is_bin_digit() && c != num_sep { if (!c.is_digit() && !c.is_letter()) || s.is_inside_string { break @@ -349,7 +352,10 @@ fn (mut s Scanner) ident_bin_number() string { } s.pos++ } - if start_pos + 2 == s.pos { + if s.text[s.pos - 1] == num_sep { + s.error('cannot use `_` at the end of a numeric literal') + } + else if start_pos + 2 == s.pos { s.pos-- // adjust error position s.error('number part of this binary is not provided') } else if has_wrong_digit { @@ -372,6 +378,9 @@ fn (mut s Scanner) ident_hex_number() string { } for s.pos < s.text.len { c := s.text[s.pos] + if c == num_sep && s.text[s.pos + 1] == num_sep { + s.error('cannot use `_` consecutively') + } if !c.is_hex_digit() && c != num_sep { if !c.is_letter() || s.is_inside_string { break @@ -383,7 +392,10 @@ fn (mut s Scanner) ident_hex_number() string { } s.pos++ } - if start_pos + 2 == s.pos { + if s.text[s.pos - 1] == num_sep { + s.error('cannot use `_` at the end of a numeric literal') + } + else if start_pos + 2 == s.pos { s.pos-- // adjust error position s.error('number part of this hexadecimal is not provided') } else if has_wrong_digit { @@ -406,6 +418,9 @@ fn (mut s Scanner) ident_oct_number() string { } for s.pos < s.text.len { c := s.text[s.pos] + if c == num_sep && s.text[s.pos + 1] == num_sep { + s.error('cannot use `_` consecutively') + } if !c.is_oct_digit() && c != num_sep { if (!c.is_digit() && !c.is_letter()) || s.is_inside_string { break @@ -417,7 +432,10 @@ fn (mut s Scanner) ident_oct_number() string { } s.pos++ } - if start_pos + 2 == s.pos { + if s.text[s.pos - 1] == num_sep { + s.error('cannot use `_` at the end of a numeric literal') + } + else if start_pos + 2 == s.pos { s.pos-- // adjust error position s.error('number part of this octal is not provided') } else if has_wrong_digit { @@ -437,6 +455,9 @@ fn (mut s Scanner) ident_dec_number() string { // scan integer part for s.pos < s.text.len { c := s.text[s.pos] + if c == num_sep && s.text[s.pos + 1] == num_sep { + s.error('cannot use `_` consecutively') + } if !c.is_digit() && c != num_sep { if !c.is_letter() || c in [`e`, `E`] || s.is_inside_string { break @@ -448,6 +469,9 @@ fn (mut s Scanner) ident_dec_number() string { } s.pos++ } + if s.text[s.pos - 1] == num_sep { + s.error('cannot use `_` at the end of a numeric literal') + } mut call_method := false // true for, e.g., 5.str(), 5.5.str(), 5e5.str() mut is_range := false // true for, e.g., 5..10 mut is_float_without_fraction := false // true for, e.g. 5.