diff --git a/vlib/compiler/scanner.v b/vlib/compiler/scanner.v index 01d3a9c5bc..d1361a1bfd 100644 --- a/vlib/compiler/scanner.v +++ b/vlib/compiler/scanner.v @@ -135,6 +135,8 @@ len:i1} } fn (s mut Scanner) ident_bin_number() string { + mut has_wrong_digit := false + mut first_wrong_digit := `\0` start_pos := s.pos s.pos += 2 // skip '0b' for { @@ -143,19 +145,30 @@ fn (s mut Scanner) ident_bin_number() string { } c := s.text[s.pos] if !c.is_bin_digit() && c != num_sep { - break + if !c.is_digit() && !c.is_letter() { + break + } + else if !has_wrong_digit { + has_wrong_digit = true + first_wrong_digit = c + } } s.pos++ } if start_pos + 2 == s.pos { s.error('number part of this binary is not provided') } + else if has_wrong_digit { + s.error('this binary number has unsuitable digit `${first_wrong_digit.str()}`') + } number := filter_num_sep(s.text.str, start_pos, s.pos) s.pos-- return number } fn (s mut Scanner) ident_hex_number() string { + mut has_wrong_digit := false + mut first_wrong_digit := `\0` start_pos := s.pos s.pos += 2 // skip '0x' for { @@ -164,19 +177,30 @@ fn (s mut Scanner) ident_hex_number() string { } c := s.text[s.pos] if !c.is_hex_digit() && c != num_sep { - break + if !c.is_letter() { + break + } + else if !has_wrong_digit { + has_wrong_digit = true + first_wrong_digit = c + } } s.pos++ } if start_pos + 2 == s.pos { s.error('number part of this hexadecimal is not provided') } + else if has_wrong_digit { + s.error('this hexadecimal number has unsuitable digit `${first_wrong_digit.str()}`') + } number := filter_num_sep(s.text.str, start_pos, s.pos) s.pos-- return number } fn (s mut Scanner) ident_oct_number() string { + mut has_wrong_digit := false + mut first_wrong_digit := `\0` start_pos := s.pos s.pos += 2 // skip '0o' for { @@ -185,13 +209,22 @@ fn (s mut Scanner) ident_oct_number() string { } c := s.text[s.pos] if !c.is_oct_digit() && c != num_sep { - break + if !c.is_digit() && !c.is_letter() { + break + } + else if !has_wrong_digit { + has_wrong_digit = true + first_wrong_digit = c + } } s.pos++ } if start_pos + 2 == s.pos { s.error('number part of this octal is not provided') } + else if has_wrong_digit { + s.error('this octal number has unsuitable digit `${first_wrong_digit.str()}`') + } number := filter_num_sep(s.text.str, start_pos, s.pos) s.pos-- return number diff --git a/vlib/v/scanner/scanner.v b/vlib/v/scanner/scanner.v index 0ce2e12a71..0ae3065fcd 100644 --- a/vlib/v/scanner/scanner.v +++ b/vlib/v/scanner/scanner.v @@ -131,6 +131,8 @@ fn filter_num_sep(txt byteptr, start int, end int) string { } fn (s mut Scanner) ident_bin_number() string { + mut has_wrong_digit := false + mut first_wrong_digit := `\0` start_pos := s.pos s.pos += 2 // skip '0b' for { @@ -139,19 +141,30 @@ fn (s mut Scanner) ident_bin_number() string { } c := s.text[s.pos] if !c.is_bin_digit() && c != num_sep { - break + if !c.is_digit() && !c.is_letter() { + break + } + else if !has_wrong_digit { + has_wrong_digit = true + first_wrong_digit = c + } } s.pos++ } if start_pos + 2 == s.pos { s.error('number part of this binary is not provided') } + else if has_wrong_digit { + s.error('this binary number has unsuitable digit `${first_wrong_digit.str()}`') + } number := filter_num_sep(s.text.str, start_pos, s.pos) s.pos-- return number } fn (s mut Scanner) ident_hex_number() string { + mut has_wrong_digit := false + mut first_wrong_digit := `\0` start_pos := s.pos s.pos += 2 // skip '0x' for { @@ -160,19 +173,30 @@ fn (s mut Scanner) ident_hex_number() string { } c := s.text[s.pos] if !c.is_hex_digit() && c != num_sep { - break + if !c.is_letter() { + break + } + else if !has_wrong_digit { + has_wrong_digit = true + first_wrong_digit = c + } } s.pos++ } if start_pos + 2 == s.pos { s.error('number part of this hexadecimal is not provided') } + else if has_wrong_digit { + s.error('this hexadecimal number has unsuitable digit `${first_wrong_digit.str()}`') + } number := filter_num_sep(s.text.str, start_pos, s.pos) s.pos-- return number } fn (s mut Scanner) ident_oct_number() string { + mut has_wrong_digit := false + mut first_wrong_digit := `\0` start_pos := s.pos s.pos += 2 // skip '0o' for { @@ -181,13 +205,22 @@ fn (s mut Scanner) ident_oct_number() string { } c := s.text[s.pos] if !c.is_oct_digit() && c != num_sep { - break + if !c.is_digit() && !c.is_letter() { + break + } + else if !has_wrong_digit { + has_wrong_digit = true + first_wrong_digit = c + } } s.pos++ } if start_pos + 2 == s.pos { s.error('number part of this octal is not provided') } + else if has_wrong_digit { + s.error('this octal number has unsuitable digit `${first_wrong_digit.str()}`') + } number := filter_num_sep(s.text.str, start_pos, s.pos) s.pos-- return number