annotate lwcc/preproc.c @ 296:83fcc1ed6ad6 ccdev

Checkpoint lwcc development Initial untested version of the preprocessor with macro expansion but without file inclusion.
author William Astle <lost@l-w.ca>
date Sat, 14 Sep 2013 20:04:38 -0600
parents
children 310df72c641d
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
296
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1 /*
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
2 lwcc/preproc.c
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
3
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
4 Copyright © 2013 William Astle
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
5
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
6 This file is part of LWTOOLS.
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
7
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
8 LWTOOLS is free software: you can redistribute it and/or modify it under the
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
9 terms of the GNU General Public License as published by the Free Software
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
10 Foundation, either version 3 of the License, or (at your option) any later
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
11 version.
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
12
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
13 This program is distributed in the hope that it will be useful, but WITHOUT
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
16 more details.
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
17
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
18 You should have received a copy of the GNU General Public License along with
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
19 this program. If not, see <http://www.gnu.org/licenses/>.
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
20 */
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
21
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
22 #include <string.h>
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
23
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
24 #include <lw_alloc.h>
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
25 #include <lw_string.h>
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
26
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
27 #include "cpp.h"
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
28 #include "strbuf.h"
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
29 #include "symbol.h"
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
30 #include "token.h"
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
31
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
32 static int expand_macro(struct preproc_info *, char *);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
33 static void process_directive(struct preproc_info *);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
34 static long eval_expr(struct preproc_info *);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
35
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
36 struct token *preproc_next_processed_token(struct preproc_info *pp)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
37 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
38 struct token *ct;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
39
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
40 again:
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
41 ct = preproc_next_token(pp);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
42 if (ct -> ttype == TOK_EOF)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
43 return ct;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
44 if (ct -> ttype == TOK_EOL)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
45 pp -> ppeolseen = 1;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
46
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
47 if (ct -> ttype == TOK_HASH && pp -> eolseen == 1)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
48 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
49 // preprocessor directive
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
50 process_directive(pp);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
51 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
52 // if we're in a false section, don't return the token; keep scanning
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
53 if (pp -> skip_level)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
54 goto again;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
55
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
56 if (ct -> ttype != TOK_WSPACE)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
57 pp -> ppeolseen = 0;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
58
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
59 if (ct -> ttype == TOK_IDENT)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
60 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
61 // possible macro expansion
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
62 if (expand_macro(pp, ct -> strval))
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
63 goto again;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
64 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
65
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
66 return ct;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
67 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
68
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
69 static struct token *preproc_next_processed_token_nws(struct preproc_info *pp)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
70 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
71 struct token *t;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
72
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
73 do
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
74 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
75 t = preproc_next_processed_token(pp);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
76 } while (t -> ttype == TOK_WSPACE);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
77 return t;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
78 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
79
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
80 static struct token *preproc_next_token_nws(struct preproc_info *pp)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
81 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
82 struct token *t;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
83
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
84 do
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
85 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
86 t = preproc_next_token(pp);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
87 } while (t -> ttype == TOK_WSPACE);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
88 return t;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
89 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
90
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
91 static void skip_eol(struct preproc_info *pp)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
92 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
93 struct token *t;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
94
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
95 if (pp -> curtok && pp -> curtok -> ttype == TOK_EOL)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
96 return;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
97 do
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
98 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
99 t = preproc_next_token(pp);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
100 } while (t -> ttype != TOK_EOL);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
101 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
102
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
103 static void check_eol(struct preproc_info *pp)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
104 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
105 struct token *t;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
106
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
107 t = preproc_next_token(pp);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
108 if (t -> ttype != TOK_EOL)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
109 preproc_throw_warning(pp, "Extra text after preprocessor directive");
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
110 skip_eol(pp);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
111 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
112
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
113 static void dir_ifdef(struct preproc_info *pp)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
114 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
115 struct token *ct;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
116
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
117 if (pp -> skip_level)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
118 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
119 pp -> skip_level++;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
120 skip_eol(pp);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
121 return;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
122 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
123
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
124 do
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
125 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
126 ct = preproc_next_token(pp);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
127 } while (ct -> ttype == TOK_WSPACE);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
128
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
129 if (ct -> ttype != TOK_IDENT)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
130 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
131 preproc_throw_error(pp, "Bad #ifdef");
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
132 skip_eol(pp);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
133 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
134
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
135 if (symtab_find(pp, ct -> strval) == NULL)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
136 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
137 pp -> skip_level++;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
138 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
139 else
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
140 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
141 pp -> found_level++;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
142 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
143 check_eol(pp);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
144 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
145
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
146 static void dir_ifndef(struct preproc_info *pp)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
147 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
148 struct token *ct;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
149
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
150 if (pp -> skip_level)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
151 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
152 pp -> skip_level++;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
153 skip_eol(pp);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
154 return;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
155 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
156
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
157 do
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
158 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
159 ct = preproc_next_token(pp);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
160 } while (ct -> ttype == TOK_WSPACE);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
161
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
162 if (ct -> ttype != TOK_IDENT)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
163 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
164 preproc_throw_error(pp, "Bad #ifdef");
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
165 skip_eol(pp);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
166 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
167
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
168 if (symtab_find(pp, ct -> strval) != NULL)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
169 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
170 pp -> skip_level++;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
171 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
172 else
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
173 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
174 pp -> found_level++;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
175 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
176 check_eol(pp);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
177 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
178
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
179 static void dir_if(struct preproc_info *pp)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
180 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
181 if (pp -> skip_level || !eval_expr(pp))
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
182 pp -> skip_level++;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
183 else
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
184 pp -> found_level++;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
185 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
186
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
187 static void dir_elif(struct preproc_info *pp)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
188 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
189 if (pp -> skip_level == 0)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
190 pp -> else_skip_level = pp -> found_level;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
191 if (pp -> skip_level)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
192 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
193 if (pp -> else_skip_level > pp -> found_level)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
194 ;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
195 else if (--(pp -> skip_level) != 0)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
196 pp -> skip_level++;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
197 else if (eval_expr(pp))
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
198 pp -> found_level++;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
199 else
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
200 pp -> skip_level++;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
201 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
202 else if (pp -> found_level)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
203 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
204 pp -> skip_level++;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
205 pp -> found_level--;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
206 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
207 else
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
208 preproc_throw_error(pp, "#elif in non-conditional section");
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
209 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
210
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
211 static void dir_else(struct preproc_info *pp)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
212 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
213 if (pp -> skip_level)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
214 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
215 if (pp -> else_skip_level > pp -> found_level)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
216 ;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
217 else if (--(pp -> skip_level) != 0)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
218 pp -> skip_level++;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
219 else
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
220 pp -> found_level++;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
221 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
222 else if (pp -> found_level)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
223 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
224 pp -> skip_level++;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
225 pp -> found_level--;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
226 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
227 else
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
228 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
229 preproc_throw_error(pp, "#else in non-conditional section");
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
230 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
231 if (pp -> else_level == pp -> found_level + pp -> skip_level)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
232 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
233 preproc_throw_error(pp, "Too many #else");
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
234 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
235 pp -> else_level = pp -> found_level + pp -> skip_level;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
236 check_eol(pp);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
237 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
238
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
239 static void dir_endif(struct preproc_info *pp)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
240 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
241 if (pp -> skip_level)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
242 pp -> skip_level--;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
243 else if (pp -> found_level)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
244 pp -> found_level--;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
245 else
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
246 preproc_throw_error(pp, "#endif in non-conditional section");
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
247 if (pp -> skip_level == 0)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
248 pp -> else_skip_level = 0;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
249 pp -> else_level = 0;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
250 check_eol(pp);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
251 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
252
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
253 static void dir_define(struct preproc_info *pp)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
254 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
255 struct token *tl = NULL;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
256 struct token *ttl;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
257 struct token *ct;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
258 int nargs = -1;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
259 int vargs = 0;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
260 char *mname = NULL;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
261
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
262 char **arglist = NULL;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
263
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
264 if (pp -> skip_level)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
265 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
266 skip_eol(pp);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
267 return;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
268 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
269
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
270 ct = preproc_next_token_nws(pp);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
271 if (ct -> ttype != TOK_IDENT)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
272 goto baddefine;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
273
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
274 mname = lw_strdup(ct -> strval);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
275 ct = preproc_next_token(pp);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
276
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
277 if (ct -> ttype == TOK_WSPACE)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
278 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
279 /* object like macro */
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
280 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
281 else if (ct -> ttype == TOK_EOL)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
282 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
283 /* object like macro - empty value */
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
284 goto out;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
285 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
286 else if (ct -> ttype == TOK_OPAREN)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
287 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
288 /* function like macro - parse args */
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
289 nargs = 0;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
290 vargs = 0;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
291 for (;;)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
292 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
293 ct = preproc_next_token_nws(pp);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
294 if (ct -> ttype == TOK_EOL)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
295 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
296 goto baddefine;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
297 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
298 if (ct -> ttype == TOK_CPAREN)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
299 break;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
300
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
301 if (ct -> ttype == TOK_IDENT)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
302 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
303 /* parameter name */
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
304 nargs++;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
305 /* record argument name */
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
306 arglist = lw_realloc(arglist, sizeof(char *) * nargs);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
307 arglist[nargs - 1] = lw_strdup(ct -> strval);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
308
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
309 /* check for end of args or comma */
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
310 ct = preproc_next_token_nws(pp);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
311 if (ct -> ttype == TOK_CPAREN)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
312 break;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
313 else if (ct -> ttype == TOK_COMMA)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
314 continue;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
315 else
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
316 goto baddefine;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
317 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
318 else if (ct -> ttype == TOK_ELLIPSIS)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
319 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
320 /* variadic macro */
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
321 vargs = 1;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
322 ct = preproc_next_token_nws(pp);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
323 if (ct -> ttype != TOK_CPAREN)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
324 goto baddefine;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
325 break;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
326 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
327 else
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
328 goto baddefine;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
329 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
330 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
331 else
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
332 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
333 baddefine:
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
334 preproc_throw_error(pp, "bad #define");
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
335 baddefine2:
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
336 skip_eol(pp);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
337 lw_free(mname);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
338 while (nargs > 0)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
339 lw_free(arglist[--nargs]);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
340 lw_free(arglist);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
341 return;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
342 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
343
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
344 for (;;)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
345 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
346 ct = preproc_next_token(pp);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
347 if (ct -> ttype == TOK_EOL)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
348 break;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
349 if (!tl)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
350 tl = ct;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
351 else
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
352 ttl -> next = ct;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
353 ttl = ct;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
354 pp -> curtok = NULL; // tell *_next_token* not to clobber token
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
355 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
356 out:
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
357 if (strcmp(mname, "defined") == 0)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
358 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
359 preproc_throw_warning(pp, "attempt to define 'defined' as a macro not allowed");
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
360 goto baddefine2;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
361 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
362 else if (symtab_find(pp, mname) != NULL)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
363 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
364 /* need to do a token compare between the old value and the new value
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
365 to decide whether to complain */
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
366 preproc_throw_warning(pp, "%s previous defined", mname);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
367 symtab_undef(pp, mname);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
368 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
369 symtab_define(pp, mname, tl, nargs, arglist, vargs);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
370 lw_free(mname);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
371 while (nargs > 0)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
372 lw_free(arglist[--nargs]);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
373 lw_free(arglist);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
374 /* no need to check for EOL here */
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
375 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
376
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
377 static void dir_undef(struct preproc_info *pp)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
378 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
379 struct token *ct;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
380 if (pp -> skip_level)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
381 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
382 skip_eol(pp);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
383 return;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
384 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
385
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
386 do
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
387 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
388 ct = preproc_next_token(pp);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
389 } while (ct -> ttype == TOK_WSPACE);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
390
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
391 if (ct -> ttype != TOK_IDENT)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
392 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
393 preproc_throw_error(pp, "Bad #undef");
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
394 skip_eol(pp);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
395 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
396
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
397 symtab_undef(pp, ct -> strval);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
398 check_eol(pp);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
399 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
400
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
401 char *streol(struct preproc_info *pp)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
402 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
403 struct strbuf *s;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
404 struct token *ct;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
405 int i;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
406
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
407 s = strbuf_new();
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
408 do
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
409 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
410 ct = preproc_next_token(pp);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
411 } while (ct -> ttype == TOK_WSPACE);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
412
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
413 while (ct -> ttype != TOK_EOL)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
414 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
415 for (i = 0; ct -> strval[i]; i++)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
416 strbuf_add(s, ct -> strval[i]);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
417 ct = preproc_next_token(pp);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
418 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
419 return strbuf_end(s);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
420 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
421
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
422 static void dir_error(struct preproc_info *pp)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
423 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
424 char *s;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
425
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
426 if (pp -> skip_level)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
427 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
428 skip_eol(pp);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
429 return;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
430 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
431
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
432 s = streol(pp);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
433 preproc_throw_error(pp, "%s", s);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
434 lw_free(s);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
435 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
436
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
437 static void dir_warning(struct preproc_info *pp)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
438 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
439 char *s;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
440
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
441 if (pp -> skip_level)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
442 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
443 skip_eol(pp);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
444 return;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
445 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
446
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
447 s = streol(pp);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
448 preproc_throw_warning(pp, "%s", s);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
449 lw_free(s);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
450 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
451
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
452 static void dir_include(struct preproc_info *pp)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
453 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
454 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
455
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
456 static void dir_line(struct preproc_info *pp)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
457 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
458 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
459
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
460 static void dir_pragma(struct preproc_info *pp)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
461 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
462 if (pp -> skip_level)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
463 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
464 skip_eol(pp);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
465 return;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
466 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
467
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
468 preproc_throw_warning(pp, "Unsupported #pragma");
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
469 skip_eol(pp);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
470 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
471
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
472 struct { char *name; void (*fn)(struct preproc_info *); } dirlist[] =
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
473 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
474 { "ifdef", dir_ifdef },
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
475 { "ifndef", dir_ifndef },
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
476 { "if", dir_if },
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
477 { "else", dir_else },
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
478 { "elif", dir_elif },
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
479 { "endif", dir_endif },
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
480 { "define", dir_define },
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
481 { "undef", dir_undef },
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
482 { "include", dir_include },
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
483 { "error", dir_error },
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
484 { "warning", dir_warning },
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
485 { "line", dir_line },
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
486 { "pragma", dir_pragma },
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
487 { NULL, NULL }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
488 };
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
489
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
490 static void process_directive(struct preproc_info *pp)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
491 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
492 struct token *ct;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
493 int i;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
494
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
495 do
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
496 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
497 ct = preproc_next_token(pp);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
498 } while (ct -> ttype == TOK_WSPACE);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
499
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
500 // NULL directive
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
501 if (ct -> ttype == TOK_EOL)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
502 return;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
503
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
504 if (ct -> ttype != TOK_IDENT)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
505 goto baddir;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
506
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
507 for (i = 0; dirlist[i].name; i++)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
508 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
509 if (strcmp(dirlist[i].name, ct -> strval) == 0)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
510 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
511 (*(dirlist[i].fn))(pp);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
512 return;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
513 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
514 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
515 baddir:
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
516 preproc_throw_error(pp, "Bad preprocessor directive");
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
517 while (ct -> ttype != TOK_EOL)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
518 ct = preproc_next_token(pp);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
519 return;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
520 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
521
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
522 /*
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
523 Evaluate a preprocessor expression
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
524 */
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
525
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
526 /* same as skip_eol() but the EOL token is not consumed */
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
527 static void skip_eoe(struct preproc_info *pp)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
528 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
529 skip_eol(pp);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
530 preproc_unget_token(pp, pp -> curtok);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
531 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
532
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
533 static long eval_expr_real(struct preproc_info *, int);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
534 static long preproc_numval(struct token *);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
535
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
536 static long eval_term_real(struct preproc_info *pp)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
537 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
538 long tval = 0;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
539 struct token *ct;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
540
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
541 eval_next:
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
542 ct = preproc_next_processed_token_nws(pp);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
543 if (ct -> ttype == TOK_EOL)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
544 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
545 preproc_throw_error(pp, "Bad expression");
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
546 return 0;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
547 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
548
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
549 switch (ct -> ttype)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
550 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
551 case TOK_OPAREN:
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
552 tval = eval_expr_real(pp, 0);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
553 ct = preproc_next_processed_token_nws(pp);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
554 if (ct -> ttype != ')')
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
555 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
556 preproc_throw_error(pp, "Unbalanced () in expression");
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
557 skip_eoe(pp);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
558 return 0;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
559 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
560 return tval;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
561
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
562 case TOK_ADD: // unary +
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
563 goto eval_next;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
564
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
565 case TOK_SUB: // unary -
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
566 tval = eval_expr_real(pp, 200);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
567 return -tval;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
568
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
569 /* NOTE: we should only get "TOK_IDENT" from an undefined macro */
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
570 case TOK_IDENT: // some sort of function, symbol, etc.
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
571 if (strcmp(ct -> strval, "defined"))
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
572 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
573 /* the defined operator */
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
574 /* any number in the "defined" bit will be
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
575 treated as a defined symbol, even zero */
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
576 ct = preproc_next_token_nws(pp);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
577 if (ct -> ttype == TOK_OPAREN)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
578 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
579 ct = preproc_next_token_nws(pp);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
580 if (ct -> ttype != TOK_IDENT)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
581 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
582 preproc_throw_error(pp, "Bad expression");
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
583 skip_eoe(pp);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
584 return 0;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
585 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
586 if (symtab_find(pp, ct -> strval) == NULL)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
587 tval = 0;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
588 else
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
589 tval = 1;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
590 ct = preproc_next_token_nws(pp);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
591 if (ct -> ttype != TOK_CPAREN)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
592 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
593 preproc_throw_error(pp, "Bad expression");
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
594 skip_eoe(pp);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
595 return 0;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
596 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
597 return tval;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
598 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
599 else if (ct -> ttype == TOK_IDENT)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
600 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
601 return (symtab_find(pp, ct -> strval) != NULL) ? 1 : 0;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
602 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
603 preproc_throw_error(pp, "Bad expression");
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
604 skip_eoe(pp);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
605 return 0;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
606 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
607 /* unknown identifier - it's zero */
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
608 return 0;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
609
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
610 /* numbers */
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
611 case TOK_NUMBER:
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
612 return preproc_numval(ct);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
613
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
614 default:
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
615 preproc_throw_error(pp, "Bad expression");
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
616 skip_eoe(pp);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
617 return 0;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
618 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
619 return 0;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
620 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
621
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
622 static long eval_expr_real(struct preproc_info *pp, int p)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
623 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
624 static const struct operinfo
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
625 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
626 int tok;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
627 int prec;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
628 } operators[] =
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
629 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
630 { TOK_ADD, 100 },
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
631 { TOK_SUB, 100 },
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
632 { TOK_STAR, 150 },
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
633 { TOK_DIV, 150 },
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
634 { TOK_MOD, 150 },
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
635 { TOK_LT, 75 },
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
636 { TOK_LE, 75 },
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
637 { TOK_GT, 75 },
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
638 { TOK_GE, 75 },
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
639 { TOK_EQ, 70 },
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
640 { TOK_NE, 70 },
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
641 { TOK_BAND, 30 },
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
642 { TOK_BOR, 25 },
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
643 { TOK_NONE, 0 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
644 };
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
645
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
646 int op;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
647 long term1, term2, term3;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
648 struct token *ct;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
649
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
650 term1 = eval_term_real(pp);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
651 eval_next:
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
652 ct = preproc_next_processed_token_nws(pp);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
653 for (op = 0; operators[op].tok != TOK_NONE; op++)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
654 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
655 if (operators[op].tok == ct -> ttype)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
656 break;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
657 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
658 /* if it isn't a recognized operator, assume end of expression */
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
659 if (operators[op].tok == TOK_NONE)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
660 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
661 preproc_unget_token(pp, ct);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
662 return term1;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
663 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
664
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
665 /* if new operation is not higher than the current precedence, let the previous op finish */
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
666 if (operators[op].prec <= p)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
667 return term1;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
668
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
669 /* get the second term */
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
670 term2 = eval_expr_real(pp, operators[op].prec);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
671
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
672 switch (operators[op].tok)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
673 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
674 case TOK_ADD:
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
675 term3 = term1 + term2;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
676 break;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
677
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
678 case TOK_SUB:
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
679 term3 = term1 - term2;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
680 break;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
681
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
682 case TOK_STAR:
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
683 term3 = term1 * term2;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
684 break;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
685
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
686 case TOK_DIV:
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
687 if (!term2)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
688 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
689 preproc_throw_warning(pp, "Division by zero");
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
690 term3 = 0;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
691 break;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
692 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
693 term3 = term1 / term2;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
694 break;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
695
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
696 case TOK_MOD:
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
697 if (!term2)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
698 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
699 preproc_throw_warning(pp, "Division by zero");
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
700 term3 = 0;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
701 break;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
702 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
703 term3 = term1 % term2;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
704 break;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
705
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
706 case TOK_BAND:
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
707 term3 = (term1 && term2);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
708 break;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
709
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
710 case TOK_BOR:
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
711 term3 = (term1 || term2);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
712 break;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
713
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
714 case TOK_EQ:
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
715 term3 = (term1 == term2);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
716 break;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
717
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
718 case TOK_NE:
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
719 term3 = (term1 != term2);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
720 break;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
721
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
722 case TOK_GT:
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
723 term3 = (term1 > term2);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
724 break;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
725
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
726 case TOK_GE:
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
727 term3 = (term1 >= term2);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
728 break;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
729
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
730 case TOK_LT:
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
731 term3 = (term1 < term2);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
732 break;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
733
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
734 case TOK_LE:
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
735 term3 = (term1 <= term2);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
736 break;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
737
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
738 default:
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
739 term3 = 0;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
740 break;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
741 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
742 term1 = term3;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
743 goto eval_next;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
744 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
745
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
746 static long eval_expr(struct preproc_info *pp)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
747 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
748 long rv;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
749
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
750 rv = eval_expr_real(pp, 0);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
751 if (pp -> curtok -> ttype != TOK_EOL)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
752 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
753 preproc_throw_error(pp, "Bad expression");
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
754 skip_eol(pp);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
755 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
756 return rv;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
757 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
758
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
759 /* convert a numeric string to a number */
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
760 long preproc_numval(struct token *t)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
761 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
762 return 0;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
763 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
764
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
765 /*
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
766 Below here is the logic for expanding a macro
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
767 */
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
768 static int expand_macro(struct preproc_info *pp, char *mname)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
769 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
770 struct symtab_e *s;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
771 struct token *t, *t2, *t3;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
772 struct token **arglist = NULL;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
773 int nargs = 0;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
774 struct expand_e *e;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
775 struct token **exparglist = NULL;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
776 int i;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
777
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
778 s = symtab_find(pp, mname);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
779 if (!s)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
780 return 0;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
781
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
782 for (e = pp -> expand_list; e; e = e -> next)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
783 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
784 /* don't expand if we're already expanding the same macro */
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
785 if (e -> s == s)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
786 return 0;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
787 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
788
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
789 if (s -> nargs == -1)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
790 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
791 /* short circuit NULL expansion */
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
792 if (s -> tl == NULL)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
793 return 1;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
794
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
795 goto expandmacro;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
796 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
797
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
798 // look for opening paren after optional whitespace
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
799 t2 = NULL;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
800 t = NULL;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
801 for (;;)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
802 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
803 t = preproc_next_token(pp);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
804 if (t -> ttype != TOK_WSPACE && t -> ttype != TOK_EOL)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
805 break;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
806 t -> next = t2;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
807 t2 = t2;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
808 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
809 if (t -> ttype != TOK_OPAREN)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
810 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
811 // not a function-like invocation
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
812 while (t2)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
813 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
814 t = t2 -> next;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
815 preproc_unget_token(pp, t2);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
816 t2 = t;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
817 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
818 return 0;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
819 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
820
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
821 // parse parameters here
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
822 t = preproc_next_token_nws(pp);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
823 nargs = 1;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
824 arglist = lw_alloc(sizeof(struct token *));
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
825 arglist[0] = NULL;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
826 t2 = NULL;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
827
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
828 while (t -> ttype != TOK_CPAREN)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
829 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
830 if (t -> ttype == TOK_EOF)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
831 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
832 preproc_throw_error(pp, "Unexpected EOF in macro call");
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
833 break;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
834 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
835 if (t -> ttype == TOK_EOL)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
836 continue;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
837 if (t -> ttype == TOK_COMMA)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
838 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
839 if (!(s -> vargs) || (nargs > s -> nargs))
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
840 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
841 nargs++;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
842 arglist = lw_realloc(arglist, sizeof(struct token *) * nargs);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
843 arglist[nargs - 1] = NULL;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
844 t2 = NULL;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
845 continue;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
846 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
847 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
848 if (t2)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
849 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
850 t2 -> next = token_dup(t);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
851 t2 = t2 -> next;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
852 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
853 else
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
854 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
855 t2 = token_dup(t);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
856 arglist[nargs - 1] = t2;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
857 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
858 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
859
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
860 if (s -> vargs)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
861 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
862 if (nargs <= s -> nargs)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
863 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
864 preproc_throw_error(pp, "Wrong number of arguments (%d) for variadic macro %s which takes %d arguments", nargs, mname, s -> nargs);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
865 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
866 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
867 else
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
868 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
869 if (s -> nargs != nargs && !(s -> nargs == 0 && nargs == 1 && arglist[nargs - 1]))
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
870 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
871 preproc_throw_error(pp, "Wrong number of arguments (%d) for macro %s which takes %d arguments", nargs, mname, s -> nargs);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
872 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
873 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
874
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
875 /* now calculate the pre-expansions of the arguments */
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
876 exparglist = lw_alloc(nargs);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
877 for (i = 0; i < nargs; i++)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
878 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
879 t2 = NULL;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
880 exparglist[i] = NULL;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
881 // NOTE: do nothing if empty argument
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
882 if (arglist[i] == NULL)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
883 continue;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
884 pp -> sourcelist = arglist[i];
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
885 for (;;)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
886 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
887 t = preproc_next_processed_token(pp);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
888 if (t -> ttype == TOK_EOF)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
889 break;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
890 if (t2)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
891 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
892 t2 -> next = token_dup(t);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
893 t2 = t2 -> next;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
894 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
895 else
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
896 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
897 t2 = token_dup(t);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
898 exparglist[i] = t2;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
899 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
900 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
901 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
902
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
903 expandmacro:
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
904 t2 = NULL;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
905 t3 = NULL;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
906
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
907 for (t = s -> tl; t; t = t -> next)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
908 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
909 if (t -> ttype == TOK_IDENT)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
910 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
911 /* identifiers might need expansion to arguments */
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
912 if (strcmp(t -> strval, "__VA_ARGS__") == 0)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
913 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
914 i = s -> nargs;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
915 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
916 else
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
917 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
918 for (i = 0; i < nargs; i++)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
919 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
920 if (strcmp(t -> strval, s -> params[i]) == 0)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
921 break;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
922 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
923 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
924 if ((i == s -> nargs) && !(s -> vargs))
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
925 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
926 struct token *te;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
927 // expand argument
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
928 // FIXME: handle # and ##
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
929 for (te = exparglist[i]; te; te = te -> next)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
930 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
931 if (t2)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
932 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
933 t2 -> next = token_dup(te);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
934 t2 = t2 -> next;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
935 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
936 else
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
937 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
938 t3 = token_dup(te);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
939 t2 = t2;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
940 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
941 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
942 continue;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
943 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
944 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
945 if (t2)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
946 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
947 t2 -> next = token_dup(t);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
948 t2 = t2 -> next;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
949 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
950 else
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
951 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
952 t3 = token_dup(t);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
953 t2 = t3;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
954 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
955 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
956
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
957 /* put the new expansion in front of the input, if relevant; if we
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
958 expanded to nothing, no need to create an expansion record or
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
959 put anything into the input queue */
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
960 if (t3)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
961 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
962 t2 -> next = token_create(TOK_ENDEXPAND, "", -1, -1, "");
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
963 t2 -> next -> next = pp -> tokqueue;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
964 pp -> tokqueue = t3;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
965
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
966 /* set up expansion record */
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
967 e = lw_alloc(sizeof(struct expand_e));
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
968 e -> next = pp -> expand_list;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
969 pp -> expand_list = e;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
970 e -> s = s;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
971 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
972
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
973 /* now clean up */
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
974 for (i = 0; i < nargs; i++)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
975 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
976 lw_free(arglist[i]);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
977 lw_free(exparglist[i]);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
978 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
979 lw_free(arglist);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
980 lw_free(exparglist);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
981
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
982 return 1;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
983 }