tok: s = "a" "b";
[neatcc.git] / tok.c
blob5af9b4cd5d0aee8245b9103105734588e7c73e34
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";
63 static int esc_char(int *c, char *s)
65 if (*s != '\\') {
66 *c = *s;
67 return 1;
69 if (strchr(esc_code, s[1])) {
70 *c = esc[strchr(esc_code, s[1]) - esc_code];
71 return 2;
73 *c = s[1];
74 return 2;
77 static long num;
79 long tok_num(void)
81 return num;
84 static void readnum(void)
86 if (buf[cur] == '0' && buf[cur + 1] == 'x') {
87 long result = 0;
88 cur += 2;
89 while (isalnum(buf[cur])) {
90 int c = buf[cur];
91 result <<= 4;
92 if (c >= '0' && c <= '9')
93 result |= c - '0';
94 else
95 result |= 10 + tolower(c) - 'a';
96 cur++;
98 num = result;
99 return;
101 if (isdigit(buf[cur])) {
102 long result = 0;
103 while (isdigit(buf[cur])) {
104 result *= 10;
105 result += buf[cur++] - '0';
107 num = result;
108 return;
110 if (buf[cur] == '\'') {
111 int ret;
112 cur += 2 + esc_char(&ret, buf + cur + 1);
113 num = ret;
114 return;
116 num = -1;
119 static char str[BUFSIZE];
120 static int str_len;
122 int tok_str(char *buf)
124 if (buf)
125 memcpy(buf, str, str_len);
126 return str_len;
129 static int readstr(char *out)
131 char *s = out;
132 char *r = buf + cur;
133 char *e = buf + len;
134 r++;
135 while (r < e && *r != '"') {
136 if (*r == '\\') {
137 int c;
138 r += esc_char(&c, r);
139 *s++ = c;
140 } else {
141 *s++ = *r++;
144 *s++ = '\0';
145 cur = r - buf + 1;
146 return s - out - 1;
149 static int id_char(int c)
151 return isalnum(c) || c == '_';
154 static int skipws(void)
156 while (1) {
157 while (cur < len && isspace(buf[cur]))
158 cur++;
159 if (cur == len)
160 return 1;
161 if (TOK2(buf + cur) != TOK2("/*"))
162 return 0;
163 while (++cur < len) {
164 if (buf[cur] == '*' && buf[cur + 1] == '/') {
165 cur += 2;
166 break;
170 return 0;
173 int tok_get(void)
175 int num;
176 if (next != -1) {
177 int tok = next;
178 next = -1;
179 return tok;
181 pre = cur;
182 if (skipws())
183 return TOK_EOF;
184 if (buf[cur] == '"') {
185 str_len = 0;
186 while (buf[cur] == '"') {
187 str_len += readstr(str + str_len);
188 if (skipws())
189 return TOK_EOF;
191 str_len++;
192 return TOK_STR;
194 if (isdigit(buf[cur]) || buf[cur] == '\'') {
195 readnum();
196 return TOK_NUM;
198 if (id_char(buf[cur])) {
199 char *s = name;
200 int i;
201 while (cur < len && id_char(buf[cur]))
202 *s++ = buf[cur++];
203 *s = '\0';
204 for (i = 0; i < ARRAY_SIZE(kwds); i++)
205 if (!strcmp(kwds[i].name, name))
206 return kwds[i].id;
207 return TOK_NAME;
209 if ((num = get_tok3(TOK3(buf + cur)))) {
210 cur += 3;
211 return num;
213 if ((num = get_tok3(TOK2(buf + cur)))) {
214 cur += 2;
215 return num;
217 if (strchr(";,{}()[]<>*&!=+-/%?:|^~.", buf[cur]))
218 return buf[cur++];
219 return -1;
222 int tok_see(void)
224 if (next == -1)
225 next = tok_get();
226 return next;
229 void tok_init(int fd)
231 int n = 0;
232 while ((n = read(fd, buf + len, sizeof(buf) - len)) > 0)
233 len += n;
234 next = -1;
237 char *tok_id(void)
239 return name;
242 long tok_addr(void)
244 return next == -1 ? cur : pre;
247 void tok_jump(long addr)
249 cur = addr;
250 pre = cur - 1;
251 next = -1;