scanner: add check for wrong decimal numbers
parent
f6c2b3a54b
commit
05ed6c57b6
|
@ -145,7 +145,7 @@ fn (s mut Scanner) ident_bin_number() string {
|
||||||
}
|
}
|
||||||
c := s.text[s.pos]
|
c := s.text[s.pos]
|
||||||
if !c.is_bin_digit() && c != num_sep {
|
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
|
break
|
||||||
}
|
}
|
||||||
else if !has_wrong_digit {
|
else if !has_wrong_digit {
|
||||||
|
@ -177,7 +177,7 @@ fn (s mut Scanner) ident_hex_number() string {
|
||||||
}
|
}
|
||||||
c := s.text[s.pos]
|
c := s.text[s.pos]
|
||||||
if !c.is_hex_digit() && c != num_sep {
|
if !c.is_hex_digit() && c != num_sep {
|
||||||
if !c.is_letter() {
|
if !c.is_letter() || s.inside_string {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
else if !has_wrong_digit {
|
else if !has_wrong_digit {
|
||||||
|
@ -209,7 +209,7 @@ fn (s mut Scanner) ident_oct_number() string {
|
||||||
}
|
}
|
||||||
c := s.text[s.pos]
|
c := s.text[s.pos]
|
||||||
if !c.is_oct_digit() && c != num_sep {
|
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
|
break
|
||||||
}
|
}
|
||||||
else if !has_wrong_digit {
|
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 {
|
fn (s mut Scanner) ident_dec_number() string {
|
||||||
|
mut has_wrong_digit := false
|
||||||
|
mut first_wrong_digit := `\0`
|
||||||
start_pos := s.pos
|
start_pos := s.pos
|
||||||
// scan integer part
|
// 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++
|
s.pos++
|
||||||
}
|
}
|
||||||
// e.g. 1..9
|
// e.g. 1..9
|
||||||
|
@ -246,11 +257,17 @@ fn (s mut Scanner) ident_dec_number() string {
|
||||||
// scan fractional part
|
// scan fractional part
|
||||||
if s.pos < s.text.len && s.text[s.pos] == `.` {
|
if s.pos < s.text.len && s.text[s.pos] == `.` {
|
||||||
s.pos++
|
s.pos++
|
||||||
for s.pos < s.text.len && s.text[s.pos].is_digit() {
|
for s.pos < s.text.len {
|
||||||
s.pos++
|
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
|
||||||
}
|
}
|
||||||
if !s.inside_string && s.pos < s.text.len && s.text[s.pos] == `f` {
|
else if !has_wrong_digit {
|
||||||
s.error('no `f` is needed for floats')
|
has_wrong_digit = true
|
||||||
|
first_wrong_digit = s.text[s.pos]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
s.pos++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// scan exponential part
|
// scan exponential part
|
||||||
|
@ -258,12 +275,19 @@ fn (s mut Scanner) ident_dec_number() string {
|
||||||
if s.expect('e', s.pos) || s.expect('E', s.pos) {
|
if s.expect('e', s.pos) || s.expect('E', s.pos) {
|
||||||
s.pos++
|
s.pos++
|
||||||
exp_start_pos := s.pos
|
exp_start_pos := s.pos
|
||||||
|
|
||||||
if s.pos < s.text.len && s.text[s.pos] in [`-`, `+`] {
|
if s.pos < s.text.len && s.text[s.pos] in [`-`, `+`] {
|
||||||
s.pos++
|
s.pos++
|
||||||
}
|
}
|
||||||
|
for s.pos < s.text.len {
|
||||||
for s.pos < s.text.len && s.text[s.pos].is_digit() {
|
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++
|
s.pos++
|
||||||
}
|
}
|
||||||
if exp_start_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')
|
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)
|
number := filter_num_sep(s.text.str, start_pos, s.pos)
|
||||||
s.pos--
|
s.pos--
|
||||||
return number
|
return number
|
||||||
|
@ -289,16 +316,15 @@ fn (s mut Scanner) ident_number() string {
|
||||||
if s.expect('0b', s.pos) {
|
if s.expect('0b', s.pos) {
|
||||||
return s.ident_bin_number()
|
return s.ident_bin_number()
|
||||||
}
|
}
|
||||||
if s.expect('0x', s.pos) {
|
else if s.expect('0x', s.pos) {
|
||||||
return s.ident_hex_number()
|
return s.ident_hex_number()
|
||||||
}
|
}
|
||||||
if s.expect('0o', s.pos) {
|
else if s.expect('0o', s.pos) {
|
||||||
return s.ident_oct_number()
|
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()
|
||||||
}
|
}
|
||||||
return s.ident_dec_number()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (s mut Scanner) skip_whitespace() {
|
fn (s mut Scanner) skip_whitespace() {
|
||||||
|
|
|
@ -141,7 +141,7 @@ fn (s mut Scanner) ident_bin_number() string {
|
||||||
}
|
}
|
||||||
c := s.text[s.pos]
|
c := s.text[s.pos]
|
||||||
if !c.is_bin_digit() && c != num_sep {
|
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
|
break
|
||||||
}
|
}
|
||||||
else if !has_wrong_digit {
|
else if !has_wrong_digit {
|
||||||
|
@ -173,7 +173,7 @@ fn (s mut Scanner) ident_hex_number() string {
|
||||||
}
|
}
|
||||||
c := s.text[s.pos]
|
c := s.text[s.pos]
|
||||||
if !c.is_hex_digit() && c != num_sep {
|
if !c.is_hex_digit() && c != num_sep {
|
||||||
if !c.is_letter() {
|
if !c.is_letter() || s.inside_string {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
else if !has_wrong_digit {
|
else if !has_wrong_digit {
|
||||||
|
@ -205,7 +205,7 @@ fn (s mut Scanner) ident_oct_number() string {
|
||||||
}
|
}
|
||||||
c := s.text[s.pos]
|
c := s.text[s.pos]
|
||||||
if !c.is_oct_digit() && c != num_sep {
|
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
|
break
|
||||||
}
|
}
|
||||||
else if !has_wrong_digit {
|
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 {
|
fn (s mut Scanner) ident_dec_number() string {
|
||||||
|
mut has_wrong_digit := false
|
||||||
|
mut first_wrong_digit := `\0`
|
||||||
start_pos := s.pos
|
start_pos := s.pos
|
||||||
// scan integer part
|
// 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++
|
s.pos++
|
||||||
}
|
}
|
||||||
// e.g. 1..9
|
// e.g. 1..9
|
||||||
|
@ -242,11 +253,17 @@ fn (s mut Scanner) ident_dec_number() string {
|
||||||
// scan fractional part
|
// scan fractional part
|
||||||
if s.pos < s.text.len && s.text[s.pos] == `.` {
|
if s.pos < s.text.len && s.text[s.pos] == `.` {
|
||||||
s.pos++
|
s.pos++
|
||||||
for s.pos < s.text.len && s.text[s.pos].is_digit() {
|
for s.pos < s.text.len {
|
||||||
s.pos++
|
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
|
||||||
}
|
}
|
||||||
if !s.inside_string && s.pos < s.text.len && s.text[s.pos] == `f` {
|
else if !has_wrong_digit {
|
||||||
s.error('no `f` is needed for floats')
|
has_wrong_digit = true
|
||||||
|
first_wrong_digit = s.text[s.pos]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
s.pos++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// scan exponential part
|
// scan exponential part
|
||||||
|
@ -257,7 +274,16 @@ fn (s mut Scanner) ident_dec_number() string {
|
||||||
if s.pos < s.text.len && s.text[s.pos] in [`-`, `+`] {
|
if s.pos < s.text.len && s.text[s.pos] in [`-`, `+`] {
|
||||||
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.inside_string {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
else if !has_wrong_digit {
|
||||||
|
has_wrong_digit = true
|
||||||
|
first_wrong_digit = s.text[s.pos]
|
||||||
|
}
|
||||||
|
}
|
||||||
s.pos++
|
s.pos++
|
||||||
}
|
}
|
||||||
if exp_start_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')
|
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)
|
number := filter_num_sep(s.text.str, start_pos, s.pos)
|
||||||
s.pos--
|
s.pos--
|
||||||
return number
|
return number
|
||||||
|
@ -283,16 +312,15 @@ fn (s mut Scanner) ident_number() string {
|
||||||
if s.expect('0b', s.pos) {
|
if s.expect('0b', s.pos) {
|
||||||
return s.ident_bin_number()
|
return s.ident_bin_number()
|
||||||
}
|
}
|
||||||
if s.expect('0x', s.pos) {
|
else if s.expect('0x', s.pos) {
|
||||||
return s.ident_hex_number()
|
return s.ident_hex_number()
|
||||||
}
|
}
|
||||||
if s.expect('0o', s.pos) {
|
else if s.expect('0o', s.pos) {
|
||||||
return s.ident_oct_number()
|
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()
|
||||||
}
|
}
|
||||||
return s.ident_dec_number()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (s mut Scanner) skip_whitespace() {
|
fn (s mut Scanner) skip_whitespace() {
|
||||||
|
|
Loading…
Reference in New Issue