Skip to content

Commit 2d0b189

Browse files
Use a lookup table for digit_value_for_base (closes #231)
1 parent 0ce7ecf commit 2d0b189

3 files changed

Lines changed: 153 additions & 20 deletions

File tree

src/builtins.c

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -677,17 +677,6 @@ static const char *k_digits58 = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmno
677677

678678
static int is_valid_numeric_base(int base) { return base >= 2 && base <= 64; }
679679

680-
static int digit_value_for_base(int base, char c) {
681-
const char *alphabet = (base == 58) ? k_digits58 : k_digits64;
682-
int limit = (base == 58) ? 58 : base;
683-
for (int i = 0; i < limit; i++) {
684-
if (alphabet[i] == c) {
685-
return i;
686-
}
687-
}
688-
return -1;
689-
}
690-
691680
static const char *base_prefix_str(int base, char *buf, size_t buflen) {
692681
switch (base) {
693682
case 2:

src/parser.c

Lines changed: 152 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
#include <stdlib.h>
66
#include <string.h>
77

8+
static void init_digit_tables(void);
9+
810
static void report_error(Parser *parser, const char *message) {
911
if (parser->panic_mode) {
1012
return;
@@ -25,6 +27,7 @@ static void report_error(Parser *parser, const char *message) {
2527
}
2628

2729
void parser_init(Parser *parser, Lexer *lexer) {
30+
init_digit_tables();
2831
parser->lexer = lexer;
2932
parser->panic_mode = false;
3033
parser->had_error = false;
@@ -396,17 +399,157 @@ static int base_from_literal_prefix(const char *s, size_t *prefix_len) {
396399
return -1;
397400
}
398401

399-
static int digit_value_for_base(int base, char c) {
400-
static const char *digits64 = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+_";
401-
static const char *digits58 = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
402-
const char *alphabet = (base == 58) ? digits58 : digits64;
403-
int limit = (base == 58) ? 58 : base;
404-
for (int i = 0; i < limit; i++) {
405-
if (alphabet[i] == c) {
406-
return i;
402+
static uint8_t k_digit64_tbl[256];
403+
static uint8_t k_digit58_tbl[256];
404+
405+
static void init_digit_tables(void) {
406+
static bool initialized = false;
407+
if (initialized) {
408+
return;
409+
}
410+
for (int i = 0; i < 256; i++) {
411+
k_digit64_tbl[i] = 0xFF;
412+
k_digit58_tbl[i] = 0xFF;
413+
}
414+
k_digit64_tbl['0'] = 0;
415+
k_digit64_tbl['1'] = 1;
416+
k_digit64_tbl['2'] = 2;
417+
k_digit64_tbl['3'] = 3;
418+
k_digit64_tbl['4'] = 4;
419+
k_digit64_tbl['5'] = 5;
420+
k_digit64_tbl['6'] = 6;
421+
k_digit64_tbl['7'] = 7;
422+
k_digit64_tbl['8'] = 8;
423+
k_digit64_tbl['9'] = 9;
424+
k_digit64_tbl['A'] = 10;
425+
k_digit64_tbl['B'] = 11;
426+
k_digit64_tbl['C'] = 12;
427+
k_digit64_tbl['D'] = 13;
428+
k_digit64_tbl['E'] = 14;
429+
k_digit64_tbl['F'] = 15;
430+
k_digit64_tbl['G'] = 16;
431+
k_digit64_tbl['H'] = 17;
432+
k_digit64_tbl['I'] = 18;
433+
k_digit64_tbl['J'] = 19;
434+
k_digit64_tbl['K'] = 20;
435+
k_digit64_tbl['L'] = 21;
436+
k_digit64_tbl['M'] = 22;
437+
k_digit64_tbl['N'] = 23;
438+
k_digit64_tbl['O'] = 24;
439+
k_digit64_tbl['P'] = 25;
440+
k_digit64_tbl['Q'] = 26;
441+
k_digit64_tbl['R'] = 27;
442+
k_digit64_tbl['S'] = 28;
443+
k_digit64_tbl['T'] = 29;
444+
k_digit64_tbl['U'] = 30;
445+
k_digit64_tbl['V'] = 31;
446+
k_digit64_tbl['W'] = 32;
447+
k_digit64_tbl['X'] = 33;
448+
k_digit64_tbl['Y'] = 34;
449+
k_digit64_tbl['Z'] = 35;
450+
k_digit64_tbl['a'] = 36;
451+
k_digit64_tbl['b'] = 37;
452+
k_digit64_tbl['c'] = 38;
453+
k_digit64_tbl['d'] = 39;
454+
k_digit64_tbl['e'] = 40;
455+
k_digit64_tbl['f'] = 41;
456+
k_digit64_tbl['g'] = 42;
457+
k_digit64_tbl['h'] = 43;
458+
k_digit64_tbl['i'] = 44;
459+
k_digit64_tbl['j'] = 45;
460+
k_digit64_tbl['k'] = 46;
461+
k_digit64_tbl['l'] = 47;
462+
k_digit64_tbl['m'] = 48;
463+
k_digit64_tbl['n'] = 49;
464+
k_digit64_tbl['o'] = 50;
465+
k_digit64_tbl['p'] = 51;
466+
k_digit64_tbl['q'] = 52;
467+
k_digit64_tbl['r'] = 53;
468+
k_digit64_tbl['s'] = 54;
469+
k_digit64_tbl['t'] = 55;
470+
k_digit64_tbl['u'] = 56;
471+
k_digit64_tbl['v'] = 57;
472+
k_digit64_tbl['w'] = 58;
473+
k_digit64_tbl['x'] = 59;
474+
k_digit64_tbl['y'] = 60;
475+
k_digit64_tbl['z'] = 61;
476+
k_digit64_tbl['+'] = 62;
477+
k_digit64_tbl['_'] = 63;
478+
479+
k_digit58_tbl['1'] = 0;
480+
k_digit58_tbl['2'] = 1;
481+
k_digit58_tbl['3'] = 2;
482+
k_digit58_tbl['4'] = 3;
483+
k_digit58_tbl['5'] = 4;
484+
k_digit58_tbl['6'] = 5;
485+
k_digit58_tbl['7'] = 6;
486+
k_digit58_tbl['8'] = 7;
487+
k_digit58_tbl['9'] = 8;
488+
k_digit58_tbl['A'] = 9;
489+
k_digit58_tbl['B'] = 10;
490+
k_digit58_tbl['C'] = 11;
491+
k_digit58_tbl['D'] = 12;
492+
k_digit58_tbl['E'] = 13;
493+
k_digit58_tbl['F'] = 14;
494+
k_digit58_tbl['G'] = 15;
495+
k_digit58_tbl['H'] = 16;
496+
k_digit58_tbl['J'] = 17;
497+
k_digit58_tbl['K'] = 18;
498+
k_digit58_tbl['L'] = 19;
499+
k_digit58_tbl['M'] = 20;
500+
k_digit58_tbl['N'] = 21;
501+
k_digit58_tbl['P'] = 22;
502+
k_digit58_tbl['Q'] = 23;
503+
k_digit58_tbl['R'] = 24;
504+
k_digit58_tbl['S'] = 25;
505+
k_digit58_tbl['T'] = 26;
506+
k_digit58_tbl['U'] = 27;
507+
k_digit58_tbl['V'] = 28;
508+
k_digit58_tbl['W'] = 29;
509+
k_digit58_tbl['X'] = 30;
510+
k_digit58_tbl['Y'] = 31;
511+
k_digit58_tbl['Z'] = 32;
512+
k_digit58_tbl['a'] = 33;
513+
k_digit58_tbl['b'] = 34;
514+
k_digit58_tbl['c'] = 35;
515+
k_digit58_tbl['d'] = 36;
516+
k_digit58_tbl['e'] = 37;
517+
k_digit58_tbl['f'] = 38;
518+
k_digit58_tbl['g'] = 39;
519+
k_digit58_tbl['h'] = 40;
520+
k_digit58_tbl['i'] = 41;
521+
k_digit58_tbl['j'] = 42;
522+
k_digit58_tbl['k'] = 43;
523+
k_digit58_tbl['m'] = 44;
524+
k_digit58_tbl['n'] = 45;
525+
k_digit58_tbl['o'] = 46;
526+
k_digit58_tbl['p'] = 47;
527+
k_digit58_tbl['q'] = 48;
528+
k_digit58_tbl['r'] = 49;
529+
k_digit58_tbl['s'] = 50;
530+
k_digit58_tbl['t'] = 51;
531+
k_digit58_tbl['u'] = 52;
532+
k_digit58_tbl['v'] = 53;
533+
k_digit58_tbl['w'] = 54;
534+
k_digit58_tbl['x'] = 55;
535+
k_digit58_tbl['y'] = 56;
536+
k_digit58_tbl['z'] = 57;
537+
initialized = true;
538+
}
539+
540+
int digit_value_for_base(int base, char c) {
541+
if (base == 58) {
542+
uint8_t v = k_digit58_tbl[(unsigned char)c];
543+
if (v == 0xFF) {
544+
return -1;
407545
}
546+
return v;
408547
}
409-
return -1;
548+
uint8_t v = k_digit64_tbl[(unsigned char)c];
549+
if (v == 0xFF) {
550+
return -1;
551+
}
552+
return v;
410553
}
411554

412555
typedef struct {

src/parser.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,5 +20,6 @@ typedef struct {
2020

2121
void parser_init(Parser *parser, Lexer *lexer);
2222
Stmt *parser_parse(Parser *parser);
23+
int digit_value_for_base(int base, char c);
2324

2425
#endif // PARSER_H

0 commit comments

Comments
 (0)