mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
scanner: add check for wrong decimal numbers
This commit is contained in:
parent
f6c2b3a54b
commit
05ed6c57b6
@ -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() {
|
||||
|
@ -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() {
|
||||
|
Loading…
Reference in New Issue
Block a user