function pointer arguments
[neatcc.git] / tok.c
blob0f0ae9d57190fced30eb526e77cfa673a3f7a5c7
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},
41 {"goto", TOK_GOTO},
44 static char *tok3[] = {
45 "<<", ">>", "++", "--", "<<=", ">>=", "...", "+=", "-=", "*=", "/=",
46 "%=", "|=", "&=", "^=", "&&", "||", "==", "!=", "<=", ">=", "->", "/*"
49 static int get_tok3(int num)
51 int i;
52 for (i = 0; i < ARRAY_SIZE(tok3); i++)
53 if (num == TOK3(tok3[i]))
54 return num;
55 return 0;
58 static char *esc_code = "abefnrtv";
59 static char *esc = "\a\b\e\f\n\r\t\v";
61 static int esc_char(int *c, char *s)
63 if (*s != '\\') {
64 *c = *s;
65 return 1;
67 if (strchr(esc_code, s[1])) {
68 *c = esc[strchr(esc_code, s[1]) - esc_code];
69 return 2;
71 *c = s[1];
72 return 2;
75 long tok_num(void)
77 if (buf[cur] == '0' && buf[cur + 1] == 'x') {
78 long result = 0;
79 cur += 2;
80 while (isalnum(buf[cur])) {
81 int c = buf[cur];
82 result <<= 4;
83 if (c >= '0' && c <= '9')
84 result |= c - '0';
85 else
86 result |= 10 + tolower(c) - 'a';
87 cur++;
89 return result;
91 if (isdigit(buf[cur])) {
92 long result = 0;
93 while (isdigit(buf[cur])) {
94 result *= 10;
95 result += buf[cur++] - '0';
97 return result;
99 if (buf[cur] == '\'') {
100 int ret;
101 cur += 2 + esc_char(&ret, buf + cur + 1);
102 return ret;
104 return -1;
107 int tok_str(char *out)
109 char *s = out;
110 char *r = buf + cur;
111 char *e = buf + len;
112 r++;
113 while (r < e && *r != '"') {
114 if (*r == '\\') {
115 int c;
116 r += esc_char(&c, r);
117 *s++ = c;
118 } else {
119 *s++ = *r++;
122 *s++ = '\0';
123 cur = r - buf + 1;
124 return s - out;
127 static int id_char(int c)
129 return isalnum(c) || c == '_';
132 static int skipws(void)
134 while (1) {
135 while (cur < len && isspace(buf[cur]))
136 cur++;
137 if (cur == len)
138 return 1;
139 if (TOK2(buf + cur) != TOK2("/*"))
140 return 0;
141 while (++cur < len) {
142 if (buf[cur] == '*' && buf[cur + 1] == '/') {
143 cur += 2;
144 break;
148 return 0;
151 int tok_get(void)
153 int num;
154 if (next != -1) {
155 int tok = next;
156 next = -1;
157 return tok;
159 if (skipws())
160 return TOK_EOF;
161 if (buf[cur] == '"')
162 return TOK_STR;
163 if (isdigit(buf[cur]) || buf[cur] == '\'')
164 return TOK_NUM;
165 if (id_char(buf[cur])) {
166 char *s = name;
167 int i;
168 while (cur < len && id_char(buf[cur]))
169 *s++ = buf[cur++];
170 *s = '\0';
171 for (i = 0; i < ARRAY_SIZE(kwds); i++)
172 if (!strcmp(kwds[i].name, name))
173 return kwds[i].id;
174 return TOK_NAME;
176 if ((num = get_tok3(TOK3(buf + cur)))) {
177 cur += 3;
178 return num;
180 if ((num = get_tok3(TOK2(buf + cur)))) {
181 cur += 2;
182 return num;
184 if (strchr(";,{}()[]<>*&!=+-/%?:|^~.", buf[cur]))
185 return buf[cur++];
186 return -1;
189 int tok_see(void)
191 if (next == -1)
192 next = tok_get();
193 return next;
196 void tok_init(int fd)
198 int n = 0;
199 while ((n = read(fd, buf + len, sizeof(buf) - len)) > 0)
200 len += n;
201 next = -1;
204 char *tok_id(void)
206 return name;