diff --git a/vlib/compiler/scanner.v b/vlib/compiler/scanner.v index d1361a1bfd..6a2d40e4eb 100644 --- a/vlib/compiler/scanner.v +++ b/vlib/compiler/scanner.v @@ -145,7 +145,7 @@ fn (s mut Scanner) ident_bin_number() string { } c := s.text[s.pos] if !c.is_bin_digit() && c != num_sep { - if !c.is_digit() && !c.is_letter() { + if (!c.is_digit() && !c.is_letter()) || s.inside_string { break } else if !has_wrong_digit { @@ -177,7 +177,7 @@ fn (s mut Scanner) ident_hex_number() string { } c := s.text[s.pos] if !c.is_hex_digit() && c != num_sep { - if !c.is_letter() { + if !c.is_letter() || s.inside_string { break } else if !has_wrong_digit { @@ -209,7 +209,7 @@ fn (s mut Scanner) ident_oct_number() string { } c := s.text[s.pos] if !c.is_oct_digit() && c != num_sep { - if !c.is_digit() && !c.is_letter() { + if (!c.is_digit() && !c.is_letter()) || s.inside_string { break } else if !has_wrong_digit { @@ -231,9 +231,20 @@ fn (s mut Scanner) ident_oct_number() string { } fn (s mut Scanner) ident_dec_number() string { + mut has_wrong_digit := false + mut first_wrong_digit := `\0` start_pos := s.pos // scan integer part - for s.pos < s.text.len && (s.text[s.pos].is_digit() || s.text[s.pos] == num_sep) { + for s.pos < s.text.len { + if !s.text[s.pos].is_digit() && s.text[s.pos] != num_sep { + if !s.text[s.pos].is_letter() || s.text[s.pos] in [`e`, `E`] || s.inside_string { + break + } + else if !has_wrong_digit { + has_wrong_digit = true + first_wrong_digit = s.text[s.pos] + } + } s.pos++ } // e.g. 1..9 @@ -246,24 +257,37 @@ fn (s mut Scanner) ident_dec_number() string { // scan fractional part if s.pos < s.text.len && s.text[s.pos] == `.` { s.pos++ - for s.pos < s.text.len && s.text[s.pos].is_digit() { + for s.pos < s.text.len { + if !s.text[s.pos].is_digit() { + if !s.text[s.pos].is_letter() || s.text[s.pos] in [`e`, `E`] || s.inside_string { + break + } + else if !has_wrong_digit { + has_wrong_digit = true + first_wrong_digit = s.text[s.pos] + } + } s.pos++ } - if !s.inside_string && s.pos < s.text.len && s.text[s.pos] == `f` { - s.error('no `f` is needed for floats') - } } // scan exponential part mut has_exponential_part := false if s.expect('e', s.pos) || s.expect('E', s.pos) { s.pos++ exp_start_pos := s.pos - if s.pos < s.text.len && s.text[s.pos] in [`-`, `+`] { s.pos++ } - - for s.pos < s.text.len && s.text[s.pos].is_digit() { + for s.pos < s.text.len { + if !s.text[s.pos].is_digit() { + if !s.text[s.pos].is_letter() || s.inside_string { + break + } + else if !has_wrong_digit { + has_wrong_digit = true + first_wrong_digit = s.text[s.pos] + } + } s.pos++ } if exp_start_pos == s.pos { @@ -280,6 +304,9 @@ fn (s mut Scanner) ident_dec_number() string { s.error('too many decimal points in number') } } + if has_wrong_digit { + s.error('this number has unsuitable digit `${first_wrong_digit.str()}`') + } number := filter_num_sep(s.text.str, start_pos, s.pos) s.pos-- return number @@ -289,16 +316,15 @@ fn (s mut Scanner) ident_number() string { if s.expect('0b', s.pos) { return s.ident_bin_number() } - if s.expect('0x', s.pos) { + else if s.expect('0x', s.pos) { return s.ident_hex_number() } - if s.expect('0o', s.pos) { + else if s.expect('0o', s.pos) { return s.ident_oct_number() } - if s.expect('0.', s.pos) || s.expect('0e', s.pos) { + else { return s.ident_dec_number() } - return s.ident_dec_number() } fn (s mut Scanner) skip_whitespace() { diff --git a/vlib/v/scanner/scanner.v b/vlib/v/scanner/scanner.v index 0ae3065fcd..559211ffe8 100644 --- a/vlib/v/scanner/scanner.v +++ b/vlib/v/scanner/scanner.v @@ -141,7 +141,7 @@ fn (s mut Scanner) ident_bin_number() string { } c := s.text[s.pos] if !c.is_bin_digit() && c != num_sep { - if !c.is_digit() && !c.is_letter() { + if (!c.is_digit() && !c.is_letter()) || s.inside_string { break } else if !has_wrong_digit { @@ -173,7 +173,7 @@ fn (s mut Scanner) ident_hex_number() string { } c := s.text[s.pos] if !c.is_hex_digit() && c != num_sep { - if !c.is_letter() { + if !c.is_letter() || s.inside_string { break } else if !has_wrong_digit { @@ -205,7 +205,7 @@ fn (s mut Scanner) ident_oct_number() string { } c := s.text[s.pos] if !c.is_oct_digit() && c != num_sep { - if !c.is_digit() && !c.is_letter() { + if (!c.is_digit() && !c.is_letter()) || s.inside_string { break } else if !has_wrong_digit { @@ -227,9 +227,20 @@ fn (s mut Scanner) ident_oct_number() string { } fn (s mut Scanner) ident_dec_number() string { + mut has_wrong_digit := false + mut first_wrong_digit := `\0` start_pos := s.pos // scan integer part - for s.pos < s.text.len && (s.text[s.pos].is_digit() || s.text[s.pos] == num_sep) { + for s.pos < s.text.len { + if !s.text[s.pos].is_digit() && s.text[s.pos] != num_sep { + if !s.text[s.pos].is_letter() || s.text[s.pos] in [`e`, `E`] || s.inside_string { + break + } + else if !has_wrong_digit { + has_wrong_digit = true + first_wrong_digit = s.text[s.pos] + } + } s.pos++ } // e.g. 1..9 @@ -242,12 +253,18 @@ fn (s mut Scanner) ident_dec_number() string { // scan fractional part if s.pos < s.text.len && s.text[s.pos] == `.` { s.pos++ - for s.pos < s.text.len && s.text[s.pos].is_digit() { + for s.pos < s.text.len { + if !s.text[s.pos].is_digit() { + if !s.text[s.pos].is_letter() || s.text[s.pos] in [`e`, `E`] || s.inside_string { + break + } + else if !has_wrong_digit { + has_wrong_digit = true + first_wrong_digit = s.text[s.pos] + } + } s.pos++ } - if !s.inside_string && s.pos < s.text.len && s.text[s.pos] == `f` { - s.error('no `f` is needed for floats') - } } // scan exponential part mut has_exponential_part := false @@ -257,7 +274,16 @@ fn (s mut Scanner) ident_dec_number() string { if s.pos < s.text.len && s.text[s.pos] in [`-`, `+`] { s.pos++ } - for s.pos < s.text.len && s.text[s.pos].is_digit() { + for s.pos < s.text.len { + if !s.text[s.pos].is_digit() { + if !s.text[s.pos].is_letter() || s.inside_string { + break + } + else if !has_wrong_digit { + has_wrong_digit = true + first_wrong_digit = s.text[s.pos] + } + } s.pos++ } if exp_start_pos == s.pos { @@ -274,6 +300,9 @@ fn (s mut Scanner) ident_dec_number() string { s.error('too many decimal points in number') } } + if has_wrong_digit { + s.error('this number has unsuitable digit `${first_wrong_digit.str()}`') + } number := filter_num_sep(s.text.str, start_pos, s.pos) s.pos-- return number @@ -283,16 +312,15 @@ fn (s mut Scanner) ident_number() string { if s.expect('0b', s.pos) { return s.ident_bin_number() } - if s.expect('0x', s.pos) { + else if s.expect('0x', s.pos) { return s.ident_hex_number() } - if s.expect('0o', s.pos) { + else if s.expect('0o', s.pos) { return s.ident_oct_number() } - if s.expect('0.', s.pos) || s.expect('0e', s.pos) { + else { return s.ident_dec_number() } - return s.ident_dec_number() } fn (s mut Scanner) skip_whitespace() {