tok: '\12' and '\x3b'
[neatcc/cc.git] / tok.c
blob1553529d7b7aaeb9563fa4ce4b6f86892f121c85
1 #include <ctype.h>
2 #include <unistd.h>
3 #include <stdlib.h>
4 #include <string.h>
5 #include "tok.h"
7 static char buf[BUFSIZE];
8 static int len;
9 static int cur;
10 static char name[NAMELEN];
11 static int next;
12 static int pre;
14 static struct {
15 char *name;
16 unsigned id;
17 } kwds[] = {
18 {"void", TOK_VOID},
19 {"static", TOK_STATIC},
20 {"extern", TOK_EXTERN},
21 {"return", TOK_RETURN},
22 {"unsigned", TOK_UNSIGNED},
23 {"signed", TOK_SIGNED},
24 {"short", TOK_SHORT},
25 {"long", TOK_LONG},
26 {"int", TOK_INT},
27 {"char", TOK_CHAR},
28 {"struct", TOK_STRUCT},
29 {"union", TOK_UNION},
30 {"enum", TOK_ENUM},
31 {"typedef", TOK_TYPEDEF},
32 {"if", TOK_IF},
33 {"else", TOK_ELSE},
34 {"for", TOK_FOR},
35 {"while", TOK_WHILE},
36 {"do", TOK_DO},
37 {"switch", TOK_SWITCH},
38 {"case", TOK_CASE},
39 {"sizeof", TOK_SIZEOF},
40 {"break", TOK_BREAK},
41 {"continue", TOK_CONTINUE},
42 {"default", TOK_DEFAULT},
43 {"goto", TOK_GOTO},
46 static char *tok3[] = {
47 "<<", ">>", "++", "--", "<<=", ">>=", "...", "+=", "-=", "*=", "/=",
48 "%=", "|=", "&=", "^=", "&&", "||", "==", "!=", "<=", ">=", "->", "/*"
51 static int get_tok3(int num)
53 int i;
54 for (i = 0; i < ARRAY_SIZE(tok3); i++)
55 if (num == TOK3(tok3[i]))
56 return num;
57 return 0;
60 static char *esc_code = "abefnrtv";
61 static char *esc = "\a\b\e\f\n\r\t\v";
62 static char *digs = "0123456789abcdef";
64 static int esc_char(int *c, char *s)
66 if (*s != '\\') {
67 *c = *s;
68 return 1;
70 if (strchr(esc_code, s[1])) {
71 *c = esc[strchr(esc_code, s[1]) - esc_code];
72 return 2;
74 if (isdigit(s[1]) || s[1] == 'x') {
75 int ret = 0;
76 int base = 8;
77 int i = 1;
78 char *d;
79 if (s[1] == 'x') {
80 base = 16;
81 i++;
83 while ((d = strchr(digs, s[i]))) {
84 ret *= base;
85 ret += d - digs;
86 i++;
88 *c = ret;
89 return i;
91 *c = s[1];
92 return 2;
95 static long num;
97 long tok_num(void)
99 return num;
102 static void readnum(void)
104 int base = 10;
105 if (buf[cur] == '0' && buf[cur + 1] == 'x') {
106 base = 16;
107 cur += 2;
109 if (strchr(digs, buf[cur])) {
110 long result = 0;
111 char *c;
112 if (base == 10 && buf[cur] == '0')
113 base = 8;
114 while ((c = strchr(digs, buf[cur]))) {
115 result *= base;
116 result += c - digs;
117 cur++;
119 num = result;
120 while (tolower(buf[cur]) == 'u' || tolower(buf[cur]) == 'l')
121 cur++;
122 return;
124 if (buf[cur] == '\'') {
125 int ret;
126 cur += 2 + esc_char(&ret, buf + cur + 1);
127 num = ret;
128 return;
130 num = -1;
133 static char str[BUFSIZE];
134 static int str_len;
136 int tok_str(char *buf)
138 if (buf)
139 memcpy(buf, str, str_len);
140 return str_len;
143 static int readstr(char *out)
145 char *s = out;
146 char *r = buf + cur;
147 char *e = buf + len;
148 r++;
149 while (r < e && *r != '"') {
150 if (*r == '\\') {
151 int c;
152 r += esc_char(&c, r);
153 *s++ = c;
154 } else {
155 *s++ = *r++;
158 *s++ = '\0';
159 cur = r - buf + 1;
160 return s - out - 1;
163 static int id_char(int c)
165 return isalnum(c) || c == '_';
168 static int skipws(void)
170 while (1) {
171 while (cur < len && isspace(buf[cur]))
172 cur++;
173 if (cur == len)
174 return 1;
175 if (TOK2(buf + cur) != TOK2("/*"))
176 return 0;
177 while (++cur < len) {
178 if (buf[cur] == '*' && buf[cur + 1] == '/') {
179 cur += 2;
180 break;
184 return 0;
187 int tok_get(void)
189 int num;
190 if (next != -1) {
191 int tok = next;
192 next = -1;
193 return tok;
195 pre = cur;
196 if (skipws())
197 return TOK_EOF;
198 if (buf[cur] == '"') {
199 str_len = 0;
200 while (buf[cur] == '"') {
201 str_len += readstr(str + str_len);
202 if (skipws())
203 return TOK_EOF;
205 str_len++;
206 return TOK_STR;
208 if (isdigit(buf[cur]) || buf[cur] == '\'') {
209 readnum();
210 return TOK_NUM;
212 if (id_char(buf[cur])) {
213 char *s = name;
214 int i;
215 while (cur < len && id_char(buf[cur]))
216 *s++ = buf[cur++];
217 *s = '\0';
218 for (i = 0; i < ARRAY_SIZE(kwds); i++)
219 if (!strcmp(kwds[i].name, name))
220 return kwds[i].id;
221 return TOK_NAME;
223 if ((num = get_tok3(TOK3(buf + cur)))) {
224 cur += 3;
225 return num;
227 if ((num = get_tok3(TOK2(buf + cur)))) {
228 cur += 2;
229 return num;
231 if (strchr(";,{}()[]<>*&!=+-/%?:|^~.", buf[cur]))
232 return buf[cur++];
233 return -1;
236 int tok_see(void)
238 if (next == -1)
239 next = tok_get();
240 return next;
243 void tok_init(int fd)
245 int n = 0;
246 while ((n = read(fd, buf + len, sizeof(buf) - len)) > 0)
247 len += n;
248 next = -1;
251 char *tok_id(void)
253 return name;
256 long tok_addr(void)
258 return next == -1 ? cur : pre;
261 void tok_jump(long addr)
263 cur = addr;
264 pre = cur - 1;
265 next = -1;