@@ -20,6 +20,26 @@ const num_sep = `_`
2020const b_lf = 10
2121const b_cr = 13
2222const backslash = `\\ `
23+ const digit_table = get_digit_table ()
24+ const letter_table = get_letter_table ()
25+
26+ @[direct_array_access]
27+ fn get_digit_table () [256 ]bool {
28+ mut res := [256 ]bool {}
29+ for c in 0 .. 256 {
30+ res[c] = u8 (c).is_digit ()
31+ }
32+ return res
33+ }
34+
35+ @[direct_array_access]
36+ fn get_letter_table () [256 ]bool {
37+ mut res := [256 ]bool {}
38+ for c in 0 .. 256 {
39+ res[c] = u8 (c).is_letter ()
40+ }
41+ return res
42+ }
2343
2444@[minify]
2545pub struct Scanner {
@@ -273,6 +293,7 @@ fn (s &Scanner) num_lit(start int, end int) string {
273293 }
274294}
275295
296+ @[direct_array_access]
276297fn (mut s Scanner) ident_bin_number () string {
277298 mut has_wrong_digit := false
278299 mut first_wrong_digit_pos := 0
@@ -288,7 +309,7 @@ fn (mut s Scanner) ident_bin_number() string {
288309 s.error ('cannot use `_` consecutively' )
289310 }
290311 if ! c.is_bin_digit () && c != num_sep {
291- if (! c. is_digit () && ! c. is_letter () ) || s.is_inside_string || s.is_nested_string {
312+ if (! digit_table[c] && ! letter_table[c] ) || s.is_inside_string || s.is_nested_string {
292313 break
293314 } else if ! has_wrong_digit {
294315 has_wrong_digit = true
@@ -332,7 +353,7 @@ fn (mut s Scanner) ident_hex_number() string {
332353 s.error ('cannot use `_` consecutively' )
333354 }
334355 if ! c.is_hex_digit () && c != num_sep {
335- if ! c. is_letter () || s.is_inside_string || s.is_nested_string {
356+ if ! letter_table[c] || s.is_inside_string || s.is_nested_string {
336357 break
337358 } else if ! has_wrong_digit {
338359 has_wrong_digit = true
@@ -357,6 +378,7 @@ fn (mut s Scanner) ident_hex_number() string {
357378 return number
358379}
359380
381+ @[direct_array_access]
360382fn (mut s Scanner) ident_oct_number () string {
361383 mut has_wrong_digit := false
362384 mut first_wrong_digit_pos := 0
@@ -372,7 +394,7 @@ fn (mut s Scanner) ident_oct_number() string {
372394 s.error ('cannot use `_` consecutively' )
373395 }
374396 if ! c.is_oct_digit () && c != num_sep {
375- if (! c. is_digit () && ! c. is_letter () ) || s.is_inside_string || s.is_nested_string {
397+ if (! digit_table[c] && ! letter_table[c] ) || s.is_inside_string || s.is_nested_string {
376398 break
377399 } else if ! has_wrong_digit {
378400 has_wrong_digit = true
@@ -409,8 +431,8 @@ fn (mut s Scanner) ident_dec_number() string {
409431 if c == num_sep && s.text[s.pos - 1 ] == num_sep {
410432 s.error ('cannot use `_` consecutively' )
411433 }
412- if ! c. is_digit () && c != num_sep {
413- if ! c. is_letter () || c in [`e` , `E` ] || s.is_inside_string || s.is_nested_string {
434+ if ! digit_table[c] && c != num_sep {
435+ if ! letter_table[c] || c in [`e` , `E` ] || s.is_inside_string || s.is_nested_string {
414436 break
415437 } else if ! has_wrong_digit {
416438 has_wrong_digit = true
@@ -431,14 +453,14 @@ fn (mut s Scanner) ident_dec_number() string {
431453 s.pos++
432454 if s.pos < s.text.len {
433455 // 5.5, 5.5.str()
434- if s.text[s.pos]. is_digit () {
456+ if digit_table[ s.text[s.pos]] {
435457 for s.pos < s.text.len {
436458 c := s.text[s.pos]
437- if ! c. is_digit () {
438- if ! c. is_letter () || c in [`e` , `E` ] || s.is_inside_string
459+ if ! digit_table[c] {
460+ if ! letter_table[c] || c in [`e` , `E` ] || s.is_inside_string
439461 || s.is_nested_string {
440462 // 5.5.str()
441- if c == `.` && s.pos + 1 < s.text.len && s.text[s.pos + 1 ]. is_letter () {
463+ if c == `.` && s.pos + 1 < s.text.len && letter_table[ s.text[s.pos + 1 ]] {
442464 call_method = true
443465 }
444466 break
@@ -456,14 +478,14 @@ fn (mut s Scanner) ident_dec_number() string {
456478 s.pos--
457479 } else if s.text[s.pos] in [`e` , `E` ] {
458480 // 5.e5
459- } else if s.text[s.pos]. is_letter () {
481+ } else if letter_table[ s.text[s.pos]] {
460482 // 5.str()
461483 call_method = true
462484 s.pos--
463485 } else {
464486 // 5.
465487 mut symbol_length := 0
466- for i := s.pos - 2 ; i > 0 && s.text[i - 1 ]. is_digit () ; i-- {
488+ for i := s.pos - 2 ; i > 0 && digit_table[ s.text[i - 1 ]] ; i-- {
467489 symbol_length++
468490 }
469491 float_symbol := s.text[s.pos - 2 - symbol_length..s.pos - 1 ]
@@ -481,10 +503,10 @@ fn (mut s Scanner) ident_dec_number() string {
481503 }
482504 for s.pos < s.text.len {
483505 c := s.text[s.pos]
484- if ! c. is_digit () {
485- if ! c. is_letter () || s.is_inside_string || s.is_nested_string {
506+ if ! digit_table[c] {
507+ if ! letter_table[c] || s.is_inside_string || s.is_nested_string {
486508 // 5e5.str()
487- if c == `.` && s.pos + 1 < s.text.len && s.text[s.pos + 1 ]. is_letter () {
509+ if c == `.` && s.pos + 1 < s.text.len && letter_table[ s.text[s.pos + 1 ]] {
488510 call_method = true
489511 }
490512 break
@@ -713,7 +735,7 @@ pub fn (mut s Scanner) text_scan() token.Token {
713735 s.is_inter_start = false
714736 }
715737 return s.new_token (.name, name, name.len)
716- } else if c. is_digit () || (c == `.` && nextc. is_digit () ) {
738+ } else if digit_table[c] || (c == `.` && digit_table[ nextc] ) {
717739 // `123`, `.123`
718740 if ! s.is_inside_string {
719741 // In C ints with `0` prefix are octal (in V they're decimal), so discarding heading zeros is needed.
@@ -723,7 +745,7 @@ pub fn (mut s Scanner) text_scan() token.Token {
723745 }
724746 mut prefix_zero_num := start_pos - s.pos // how many prefix zeros should be jumped
725747 // for 0b, 0o, 0x the heading zero shouldn't be jumped
726- if start_pos == s.text.len || (c == `0` && ! s.text[start_pos]. is_digit () ) {
748+ if start_pos == s.text.len || (c == `0` && ! digit_table[ s.text[start_pos]] ) {
727749 prefix_zero_num--
728750 }
729751 s.pos + = prefix_zero_num // jump these zeros
@@ -1265,7 +1287,7 @@ pub fn (mut s Scanner) ident_string() string {
12651287 s.u32_ escapes_pos << s.pos - 1
12661288 }
12671289 // Unknown escape sequence
1268- if ! util.is_escape_sequence (c) && ! c. is_digit () && c != `\n ` {
1290+ if ! util.is_escape_sequence (c) && ! digit_table[c] && c != `\n ` {
12691291 s.error ('`${c .ascii_str ()}` unknown escape sequence' )
12701292 }
12711293 }
@@ -1609,7 +1631,7 @@ pub fn (mut s Scanner) ident_char() string {
16091631 s.error_with_pos ('invalid character literal, use \` \\ n\` instead' , lspos)
16101632 } else if c.len > len {
16111633 ch := c[c.len - 1 ]
1612- if ! util.is_escape_sequence (ch) && ! ch. is_digit () {
1634+ if ! util.is_escape_sequence (ch) && ! digit_table[ch] {
16131635 s.error ('`${ch .ascii_str ()}` unknown escape sequence' )
16141636 }
16151637 }
0 commit comments