improvements to number lexing
[cparser] / token.c
1 #include <config.h>
2
3 #include "token_t.h"
4
5 #include <assert.h>
6 #include <stdio.h>
7
8 #include "symbol.h"
9 #include "adt/array.h"
10
11 static symbol_t *token_symbols[T_LAST_TOKEN];
12
13 void init_tokens(void)
14 {
15         symbol_t *symbol;
16
17         memset(token_symbols, 0, T_LAST_TOKEN * sizeof(token_symbols[0]));
18
19 #define T(x,str,val)                                               \
20         assert(T_##x >= 0 && T_##x < T_LAST_TOKEN);                    \
21         symbol               = symbol_table_insert(str);               \
22         symbol->ID           = T_##x;                                  \
23         token_symbols[T_##x] = symbol;
24
25 #define TS(x,str,val)                                              \
26         assert(T_##x >= 0 && T_##x < T_LAST_TOKEN);                    \
27         symbol               = symbol_table_insert(str);               \
28         token_symbols[T_##x] = symbol;
29
30 #include "tokens.inc"
31
32 #undef TS
33 #undef T
34
35 #define T(x,str,val)                                               \
36         assert(TP_##x >= 0 && TP_##x < TP_LAST_TOKEN);                 \
37         symbol               = symbol_table_insert(str);               \
38         symbol->pp_ID        = TP_##x;
39
40 #include "tokens_preprocessor.inc"
41
42 #undef T
43 }
44
45 void exit_tokens(void)
46 {
47 }
48
49 void print_token_type(FILE *f, token_type_t token_type)
50 {
51         if(token_type == T_EOF) {
52                 fputs("end of file", f);
53                 return;
54         }
55         if(token_type == T_ERROR) {
56                 fputs("error", f);
57                 return;
58         }
59
60         int token_symbols_len = T_LAST_TOKEN;
61         if(token_type < 0 || token_type >= token_symbols_len) {
62                 fputs("invalid token", f);
63                 return;
64         }
65
66         const symbol_t *symbol = token_symbols[token_type];
67         if(symbol != NULL) {
68                 fprintf(f, "'%s'", symbol->string);
69         } else {
70                 if(token_type >= 0 && token_type < 256) {
71                         fprintf(f, "'%c'", token_type);
72                         return;
73                 }
74                 fputs("unknown token", f);
75         }
76 }
77
78 void print_token(FILE *f, const token_t *token)
79 {
80         switch(token->type) {
81         case T_IDENTIFIER:
82                 fprintf(f, "symbol '%s'", token->v.symbol->string);
83                 break;
84         case T_INTEGER:
85                 fprintf(f, "integer number %lld", token->v.intvalue);
86                 break;
87         case T_FLOATINGPOINT:
88                 fprintf(f, "floatingpointer number %LF", token->v.floatvalue);
89                 break;
90         case T_STRING_LITERAL:
91                 fprintf(f, "string '%s'", token->v.string);
92                 break;
93         default:
94                 print_token_type(f, (token_type_t)token->type);
95                 break;
96         }
97 }