gen: handle more than 6 args
[neatcc/cc.git] / tok.c
blob3d2283a8a7194f82b0fd75302ecc764b84135f44
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;
13 static struct {
14 char *name;
15 unsigned id;
16 } kwds[] = {
17 {"void", TOK_VOID},
18 {"static", TOK_STATIC},
19 {"return", TOK_RETURN},
20 {"unsigned", TOK_UNSIGNED},
21 {"signed", TOK_SIGNED},
22 {"short", TOK_SHORT},
23 {"long", TOK_LONG},
24 {"int", TOK_INT},
25 {"char", TOK_CHAR},
26 {"struct", TOK_STRUCT},
27 {"union", TOK_UNION},
28 {"enum", TOK_ENUM},
29 {"typedef", TOK_TYPEDEF},
30 {"if", TOK_IF},
31 {"else", TOK_ELSE},
32 {"for", TOK_FOR},
33 {"while", TOK_WHILE},
34 {"do", TOK_DO},
35 {"switch", TOK_SWITCH},
36 {"case", TOK_CASE},
37 {"sizeof", TOK_SIZEOF},
38 {"break", TOK_BREAK},
39 {"continue", TOK_CONTINUE},
40 {"default", TOK_DEFAULT},
43 static char *tok3[] = {
44 "<<", ">>", "++", "--", "<<=", ">>=", "...", "+=", "-=", "*=", "/=",
45 "%=", "|=", "&=", "^=", "&&", "||", "==", "!=", "<=", ">=", "->", "/*"
48 static int get_tok3(int num)
50 int i;
51 for (i = 0; i < ARRAY_SIZE(tok3); i++)
52 if (num == TOK3(tok3[i]))
53 return num;
54 return 0;
57 static char *esc_code = "abefnrtv";
58 static char *esc = "\a\b\e\f\n\r\t\v";
60 static int esc_char(int *c, char *s)
62 if (*s != '\\') {
63 *c = *s;
64 return 1;
66 if (strchr(esc_code, s[1])) {
67 *c = esc[strchr(esc_code, s[1]) - esc_code];
68 return 2;
70 *c = s[1];
71 return 2;
74 long tok_num(void)
76 if (buf[cur] == '0' && buf[cur + 1] == 'x') {
77 long result = 0;
78 cur += 2;
79 while (isalnum(buf[cur])) {
80 int c = buf[cur];
81 result <<= 4;
82 if (c >= '0' && c <= '9')
83 result |= c - '0';
84 else
85 result |= 10 + tolower(c) - 'a';
86 cur++;
88 return result;
90 if (isdigit(buf[cur])) {
91 long result = 0;
92 while (isdigit(buf[cur])) {
93 result *= 10;
94 result += buf[cur++] - '0';
96 return result;
98 if (buf[cur] == '\'') {
99 int ret;
100 cur += 2 + esc_char(&ret, buf + cur + 1);
101 return ret;
103 return -1;
106 int tok_str(char *out)
108 char *s = out;
109 char *r = buf + cur;
110 char *e = buf + len;
111 r++;
112 while (r < e && *r != '"') {
113 if (*r == '\\') {
114 int c;
115 r += esc_char(&c, r);
116 *s++ = c;
117 } else {
118 *s++ = *r++;
121 *s++ = '\0';
122 cur = r - buf + 1;
123 return s - out;
126 static int id_char(int c)
128 return isalnum(c) || c == '_';
131 static int skipws(void)
133 while (1) {
134 while (cur < len && isspace(buf[cur]))
135 cur++;
136 if (cur == len)
137 return 1;
138 if (TOK2(buf + cur) != TOK2("/*"))
139 return 0;
140 while (++cur < len) {
141 if (buf[cur] == '*' && buf[cur + 1] == '/') {
142 cur += 2;
143 break;
147 return 0;
150 int tok_get(void)
152 int num;
153 if (next != -1) {
154 int tok = next;
155 next = -1;
156 return tok;
158 if (skipws())
159 return TOK_EOF;
160 if (buf[cur] == '"')
161 return TOK_STR;
162 if (isdigit(buf[cur]) || buf[cur] == '\'')
163 return TOK_NUM;
164 if (id_char(buf[cur])) {
165 char *s = name;
166 int i;
167 while (cur < len && id_char(buf[cur]))
168 *s++ = buf[cur++];
169 *s = '\0';
170 for (i = 0; i < ARRAY_SIZE(kwds); i++)
171 if (!strcmp(kwds[i].name, name))
172 return kwds[i].id;
173 return TOK_NAME;
175 if ((num = get_tok3(TOK3(buf + cur)))) {
176 cur += 3;
177 return num;
179 if ((num = get_tok3(TOK2(buf + cur)))) {
180 cur += 2;
181 return num;
183 if (strchr(";,{}()[]<>*&!=+-/%?:|^~.", buf[cur]))
184 return buf[cur++];
185 return -1;
188 int tok_see(void)
190 if (next == -1)
191 next = tok_get();
192 return next;
195 void tok_init(int fd)
197 int n = 0;
198 while ((n = read(fd, buf + len, sizeof(buf) - len)) > 0)
199 len += n;
200 next = -1;
203 char *tok_id(void)
205 return name;