annotate lwcc/preproc.c @ 298:6112c67728ba ccdev

Add stringification and token concatenation Add support for # and ## in macro expansion by the preprocessor (stringification and token concatenation). Totally untested.
author William Astle <lost@l-w.ca>
date Sat, 14 Sep 2013 22:42:53 -0600
parents 310df72c641d
children 856caf91ffaa
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 *);
298
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
35 extern struct token *preproc_lex_next_token(struct preproc_info *);
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
36
296
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 *preproc_next_processed_token(struct preproc_info *pp)
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 struct token *ct;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
41
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
42 again:
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
43 ct = preproc_next_token(pp);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
44 if (ct -> ttype == TOK_EOF)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
45 return ct;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
46 if (ct -> ttype == TOK_EOL)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
47 pp -> ppeolseen = 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 if (ct -> ttype == TOK_HASH && pp -> eolseen == 1)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
50 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
51 // preprocessor directive
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
52 process_directive(pp);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
53 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
54 // 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
55 if (pp -> skip_level)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
56 goto again;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
57
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
58 if (ct -> ttype != TOK_WSPACE)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
59 pp -> ppeolseen = 0;
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 if (ct -> ttype == TOK_IDENT)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
62 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
63 // possible macro expansion
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
64 if (expand_macro(pp, ct -> strval))
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
65 goto again;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
66 }
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 return ct;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
69 }
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 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
72 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
73 struct token *t;
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 do
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
76 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
77 t = preproc_next_processed_token(pp);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
78 } while (t -> ttype == TOK_WSPACE);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
79 return t;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
80 }
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 static struct token *preproc_next_token_nws(struct preproc_info *pp)
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 struct token *t;
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 do
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
87 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
88 t = preproc_next_token(pp);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
89 } while (t -> ttype == TOK_WSPACE);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
90 return t;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
91 }
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 static void skip_eol(struct preproc_info *pp)
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 struct token *t;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
96
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
97 if (pp -> curtok && pp -> curtok -> ttype == TOK_EOL)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
98 return;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
99 do
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
100 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
101 t = preproc_next_token(pp);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
102 } while (t -> ttype != TOK_EOL);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
103 }
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 static void check_eol(struct preproc_info *pp)
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 struct token *t;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
108
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
109 t = preproc_next_token(pp);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
110 if (t -> ttype != TOK_EOL)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
111 preproc_throw_warning(pp, "Extra text after preprocessor directive");
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
112 skip_eol(pp);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
113 }
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 static void dir_ifdef(struct preproc_info *pp)
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 struct token *ct;
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 if (pp -> skip_level)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
120 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
121 pp -> skip_level++;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
122 skip_eol(pp);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
123 return;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
124 }
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 do
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
127 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
128 ct = preproc_next_token(pp);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
129 } while (ct -> ttype == TOK_WSPACE);
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 if (ct -> ttype != TOK_IDENT)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
132 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
133 preproc_throw_error(pp, "Bad #ifdef");
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
134 skip_eol(pp);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
135 }
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 if (symtab_find(pp, ct -> strval) == NULL)
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 pp -> skip_level++;
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 else
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 pp -> found_level++;
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 check_eol(pp);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
146 }
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 static void dir_ifndef(struct preproc_info *pp)
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 struct token *ct;
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 if (pp -> skip_level)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
153 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
154 pp -> skip_level++;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
155 skip_eol(pp);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
156 return;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
157 }
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 do
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
160 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
161 ct = preproc_next_token(pp);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
162 } while (ct -> ttype == TOK_WSPACE);
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 if (ct -> ttype != TOK_IDENT)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
165 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
166 preproc_throw_error(pp, "Bad #ifdef");
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
167 skip_eol(pp);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
168 }
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 if (symtab_find(pp, ct -> strval) != NULL)
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 pp -> skip_level++;
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 else
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 pp -> found_level++;
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 check_eol(pp);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
179 }
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 static void dir_if(struct preproc_info *pp)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
182 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
183 if (pp -> skip_level || !eval_expr(pp))
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
184 pp -> skip_level++;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
185 else
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
186 pp -> found_level++;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
187 }
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 static void dir_elif(struct preproc_info *pp)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
190 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
191 if (pp -> skip_level == 0)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
192 pp -> else_skip_level = pp -> found_level;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
193 if (pp -> skip_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 if (pp -> else_skip_level > pp -> found_level)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
196 ;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
197 else if (--(pp -> skip_level) != 0)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
198 pp -> skip_level++;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
199 else if (eval_expr(pp))
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
200 pp -> found_level++;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
201 else
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
202 pp -> skip_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 else if (pp -> found_level)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
205 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
206 pp -> skip_level++;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
207 pp -> found_level--;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
208 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
209 else
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
210 preproc_throw_error(pp, "#elif in non-conditional section");
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
211 }
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 static void dir_else(struct preproc_info *pp)
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 -> skip_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 if (pp -> else_skip_level > pp -> found_level)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
218 ;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
219 else if (--(pp -> skip_level) != 0)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
220 pp -> skip_level++;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
221 else
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
222 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 else if (pp -> found_level)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
225 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
226 pp -> skip_level++;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
227 pp -> found_level--;
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 else
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 preproc_throw_error(pp, "#else in non-conditional section");
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 if (pp -> else_level == pp -> found_level + pp -> skip_level)
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 preproc_throw_error(pp, "Too many #else");
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
236 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
237 pp -> else_level = pp -> found_level + pp -> skip_level;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
238 check_eol(pp);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
239 }
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 static void dir_endif(struct preproc_info *pp)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
242 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
243 if (pp -> skip_level)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
244 pp -> skip_level--;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
245 else if (pp -> found_level)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
246 pp -> found_level--;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
247 else
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
248 preproc_throw_error(pp, "#endif in non-conditional section");
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
249 if (pp -> skip_level == 0)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
250 pp -> else_skip_level = 0;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
251 pp -> else_level = 0;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
252 check_eol(pp);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
253 }
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 static void dir_define(struct preproc_info *pp)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
256 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
257 struct token *tl = NULL;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
258 struct token *ttl;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
259 struct token *ct;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
260 int nargs = -1;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
261 int vargs = 0;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
262 char *mname = 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 char **arglist = NULL;
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 if (pp -> skip_level)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
267 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
268 skip_eol(pp);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
269 return;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
270 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
271
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
272 ct = preproc_next_token_nws(pp);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
273 if (ct -> ttype != TOK_IDENT)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
274 goto baddefine;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
275
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
276 mname = lw_strdup(ct -> strval);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
277 ct = preproc_next_token(pp);
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 if (ct -> ttype == TOK_WSPACE)
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 /* object like macro */
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 else if (ct -> ttype == TOK_EOL)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
284 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
285 /* object like macro - empty value */
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
286 goto out;
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 else if (ct -> ttype == TOK_OPAREN)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
289 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
290 /* function like macro - parse args */
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
291 nargs = 0;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
292 vargs = 0;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
293 for (;;)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
294 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
295 ct = preproc_next_token_nws(pp);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
296 if (ct -> ttype == TOK_EOL)
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 goto baddefine;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
299 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
300 if (ct -> ttype == TOK_CPAREN)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
301 break;
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 if (ct -> ttype == TOK_IDENT)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
304 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
305 /* parameter name */
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
306 nargs++;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
307 /* record argument name */
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
308 arglist = lw_realloc(arglist, sizeof(char *) * nargs);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
309 arglist[nargs - 1] = lw_strdup(ct -> strval);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
310
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
311 /* check for end of args or comma */
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
312 ct = preproc_next_token_nws(pp);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
313 if (ct -> ttype == TOK_CPAREN)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
314 break;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
315 else if (ct -> ttype == TOK_COMMA)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
316 continue;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
317 else
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
318 goto baddefine;
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 else if (ct -> ttype == TOK_ELLIPSIS)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
321 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
322 /* variadic macro */
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
323 vargs = 1;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
324 ct = preproc_next_token_nws(pp);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
325 if (ct -> ttype != TOK_CPAREN)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
326 goto baddefine;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
327 break;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
328 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
329 else
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
330 goto baddefine;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
331 }
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 else
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
334 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
335 baddefine:
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
336 preproc_throw_error(pp, "bad #define");
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
337 baddefine2:
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
338 skip_eol(pp);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
339 lw_free(mname);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
340 while (nargs > 0)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
341 lw_free(arglist[--nargs]);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
342 lw_free(arglist);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
343 return;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
344 }
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 for (;;)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
347 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
348 ct = preproc_next_token(pp);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
349 if (ct -> ttype == TOK_EOL)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
350 break;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
351 if (!tl)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
352 tl = ct;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
353 else
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
354 ttl -> next = ct;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
355 ttl = ct;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
356 pp -> curtok = NULL; // tell *_next_token* not to clobber token
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
357 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
358 out:
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
359 if (strcmp(mname, "defined") == 0)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
360 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
361 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
362 goto baddefine2;
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 else if (symtab_find(pp, mname) != NULL)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
365 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
366 /* 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
367 to decide whether to complain */
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
368 preproc_throw_warning(pp, "%s previous defined", mname);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
369 symtab_undef(pp, mname);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
370 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
371 symtab_define(pp, mname, tl, nargs, arglist, vargs);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
372 lw_free(mname);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
373 while (nargs > 0)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
374 lw_free(arglist[--nargs]);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
375 lw_free(arglist);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
376 /* no need to check for EOL here */
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
377 }
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 static void dir_undef(struct preproc_info *pp)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
380 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
381 struct token *ct;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
382 if (pp -> skip_level)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
383 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
384 skip_eol(pp);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
385 return;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
386 }
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 do
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
389 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
390 ct = preproc_next_token(pp);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
391 } while (ct -> ttype == TOK_WSPACE);
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 if (ct -> ttype != TOK_IDENT)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
394 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
395 preproc_throw_error(pp, "Bad #undef");
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
396 skip_eol(pp);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
397 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
398
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
399 symtab_undef(pp, ct -> strval);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
400 check_eol(pp);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
401 }
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 char *streol(struct preproc_info *pp)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
404 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
405 struct strbuf *s;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
406 struct token *ct;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
407 int i;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
408
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
409 s = strbuf_new();
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
410 do
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
411 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
412 ct = preproc_next_token(pp);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
413 } while (ct -> ttype == TOK_WSPACE);
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 while (ct -> ttype != TOK_EOL)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
416 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
417 for (i = 0; ct -> strval[i]; i++)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
418 strbuf_add(s, ct -> strval[i]);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
419 ct = preproc_next_token(pp);
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 return strbuf_end(s);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
422 }
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 static void dir_error(struct preproc_info *pp)
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 char *s;
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 if (pp -> skip_level)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
429 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
430 skip_eol(pp);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
431 return;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
432 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
433
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
434 s = streol(pp);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
435 preproc_throw_error(pp, "%s", s);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
436 lw_free(s);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
437 }
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 static void dir_warning(struct preproc_info *pp)
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 char *s;
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 if (pp -> skip_level)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
444 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
445 skip_eol(pp);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
446 return;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
447 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
448
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
449 s = streol(pp);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
450 preproc_throw_warning(pp, "%s", s);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
451 lw_free(s);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
452 }
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 static void dir_include(struct preproc_info *pp)
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 }
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 static void dir_line(struct preproc_info *pp)
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 }
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 static void dir_pragma(struct preproc_info *pp)
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 if (pp -> skip_level)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
465 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
466 skip_eol(pp);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
467 return;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
468 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
469
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
470 preproc_throw_warning(pp, "Unsupported #pragma");
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
471 skip_eol(pp);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
472 }
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 struct { char *name; void (*fn)(struct preproc_info *); } dirlist[] =
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
475 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
476 { "ifdef", dir_ifdef },
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
477 { "ifndef", dir_ifndef },
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
478 { "if", dir_if },
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
479 { "else", dir_else },
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
480 { "elif", dir_elif },
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
481 { "endif", dir_endif },
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
482 { "define", dir_define },
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
483 { "undef", dir_undef },
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
484 { "include", dir_include },
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
485 { "error", dir_error },
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
486 { "warning", dir_warning },
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
487 { "line", dir_line },
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
488 { "pragma", dir_pragma },
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
489 { NULL, NULL }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
490 };
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 static void process_directive(struct preproc_info *pp)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
493 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
494 struct token *ct;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
495 int i;
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 do
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
498 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
499 ct = preproc_next_token(pp);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
500 } while (ct -> ttype == TOK_WSPACE);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
501
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
502 // NULL directive
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
503 if (ct -> ttype == TOK_EOL)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
504 return;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
505
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
506 if (ct -> ttype != TOK_IDENT)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
507 goto baddir;
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 for (i = 0; dirlist[i].name; i++)
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 if (strcmp(dirlist[i].name, ct -> strval) == 0)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
512 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
513 (*(dirlist[i].fn))(pp);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
514 return;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
515 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
516 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
517 baddir:
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
518 preproc_throw_error(pp, "Bad preprocessor directive");
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
519 while (ct -> ttype != TOK_EOL)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
520 ct = preproc_next_token(pp);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
521 return;
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
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 Evaluate a preprocessor expression
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
526 */
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
527
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
528 /* same as skip_eol() but the EOL token is not consumed */
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
529 static void skip_eoe(struct preproc_info *pp)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
530 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
531 skip_eol(pp);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
532 preproc_unget_token(pp, pp -> curtok);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
533 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
534
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
535 static long eval_expr_real(struct preproc_info *, int);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
536 static long preproc_numval(struct token *);
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 static long eval_term_real(struct preproc_info *pp)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
539 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
540 long tval = 0;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
541 struct token *ct;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
542
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
543 eval_next:
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
544 ct = preproc_next_processed_token_nws(pp);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
545 if (ct -> ttype == TOK_EOL)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
546 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
547 preproc_throw_error(pp, "Bad expression");
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
548 return 0;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
549 }
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 switch (ct -> ttype)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
552 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
553 case TOK_OPAREN:
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
554 tval = eval_expr_real(pp, 0);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
555 ct = preproc_next_processed_token_nws(pp);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
556 if (ct -> ttype != ')')
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
557 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
558 preproc_throw_error(pp, "Unbalanced () in expression");
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
559 skip_eoe(pp);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
560 return 0;
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 return tval;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
563
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
564 case TOK_ADD: // unary +
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
565 goto eval_next;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
566
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
567 case TOK_SUB: // unary -
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
568 tval = eval_expr_real(pp, 200);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
569 return -tval;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
570
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
571 /* NOTE: we should only get "TOK_IDENT" from an undefined macro */
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
572 case TOK_IDENT: // some sort of function, symbol, etc.
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
573 if (strcmp(ct -> strval, "defined"))
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
574 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
575 /* the defined operator */
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
576 /* any number in the "defined" bit will be
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
577 treated as a defined symbol, even zero */
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
578 ct = preproc_next_token_nws(pp);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
579 if (ct -> ttype == TOK_OPAREN)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
580 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
581 ct = preproc_next_token_nws(pp);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
582 if (ct -> ttype != TOK_IDENT)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
583 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
584 preproc_throw_error(pp, "Bad expression");
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
585 skip_eoe(pp);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
586 return 0;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
587 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
588 if (symtab_find(pp, ct -> strval) == NULL)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
589 tval = 0;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
590 else
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
591 tval = 1;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
592 ct = preproc_next_token_nws(pp);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
593 if (ct -> ttype != TOK_CPAREN)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
594 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
595 preproc_throw_error(pp, "Bad expression");
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
596 skip_eoe(pp);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
597 return 0;
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 return tval;
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 else if (ct -> ttype == TOK_IDENT)
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 return (symtab_find(pp, ct -> strval) != NULL) ? 1 : 0;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
604 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
605 preproc_throw_error(pp, "Bad expression");
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
606 skip_eoe(pp);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
607 return 0;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
608 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
609 /* unknown identifier - it's zero */
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
610 return 0;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
611
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
612 /* numbers */
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
613 case TOK_NUMBER:
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
614 return preproc_numval(ct);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
615
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
616 default:
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
617 preproc_throw_error(pp, "Bad expression");
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
618 skip_eoe(pp);
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 return 0;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
622 }
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 long eval_expr_real(struct preproc_info *pp, int p)
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 static const struct operinfo
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
627 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
628 int tok;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
629 int prec;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
630 } operators[] =
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
631 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
632 { TOK_ADD, 100 },
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
633 { TOK_SUB, 100 },
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
634 { TOK_STAR, 150 },
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
635 { TOK_DIV, 150 },
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
636 { TOK_MOD, 150 },
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
637 { TOK_LT, 75 },
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
638 { TOK_LE, 75 },
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
639 { TOK_GT, 75 },
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
640 { TOK_GE, 75 },
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
641 { TOK_EQ, 70 },
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
642 { TOK_NE, 70 },
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
643 { TOK_BAND, 30 },
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
644 { TOK_BOR, 25 },
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
645 { TOK_NONE, 0 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
646 };
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
647
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
648 int op;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
649 long term1, term2, term3;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
650 struct token *ct;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
651
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
652 term1 = eval_term_real(pp);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
653 eval_next:
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
654 ct = preproc_next_processed_token_nws(pp);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
655 for (op = 0; operators[op].tok != TOK_NONE; op++)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
656 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
657 if (operators[op].tok == ct -> ttype)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
658 break;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
659 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
660 /* if it isn't a recognized operator, assume end of expression */
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
661 if (operators[op].tok == TOK_NONE)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
662 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
663 preproc_unget_token(pp, ct);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
664 return term1;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
665 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
666
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
667 /* 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
668 if (operators[op].prec <= p)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
669 return term1;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
670
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
671 /* get the second term */
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
672 term2 = eval_expr_real(pp, operators[op].prec);
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 switch (operators[op].tok)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
675 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
676 case TOK_ADD:
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
677 term3 = term1 + term2;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
678 break;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
679
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
680 case TOK_SUB:
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
681 term3 = term1 - term2;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
682 break;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
683
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
684 case TOK_STAR:
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
685 term3 = term1 * term2;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
686 break;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
687
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
688 case TOK_DIV:
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
689 if (!term2)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
690 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
691 preproc_throw_warning(pp, "Division by zero");
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
692 term3 = 0;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
693 break;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
694 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
695 term3 = term1 / term2;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
696 break;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
697
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
698 case TOK_MOD:
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
699 if (!term2)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
700 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
701 preproc_throw_warning(pp, "Division by zero");
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
702 term3 = 0;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
703 break;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
704 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
705 term3 = term1 % term2;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
706 break;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
707
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
708 case TOK_BAND:
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
709 term3 = (term1 && term2);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
710 break;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
711
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
712 case TOK_BOR:
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
713 term3 = (term1 || term2);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
714 break;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
715
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
716 case TOK_EQ:
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
717 term3 = (term1 == term2);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
718 break;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
719
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
720 case TOK_NE:
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
721 term3 = (term1 != term2);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
722 break;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
723
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
724 case TOK_GT:
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
725 term3 = (term1 > term2);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
726 break;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
727
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
728 case TOK_GE:
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
729 term3 = (term1 >= term2);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
730 break;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
731
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
732 case TOK_LT:
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
733 term3 = (term1 < term2);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
734 break;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
735
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
736 case TOK_LE:
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
737 term3 = (term1 <= term2);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
738 break;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
739
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
740 default:
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
741 term3 = 0;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
742 break;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
743 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
744 term1 = term3;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
745 goto eval_next;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
746 }
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 static long eval_expr(struct preproc_info *pp)
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 long rv;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
751
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
752 rv = eval_expr_real(pp, 0);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
753 if (pp -> curtok -> ttype != TOK_EOL)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
754 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
755 preproc_throw_error(pp, "Bad expression");
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
756 skip_eol(pp);
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 return rv;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
759 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
760
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
761 /* convert a numeric string to a number */
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
762 long preproc_numval(struct token *t)
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 return 0;
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
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 Below here is the logic for expanding a macro
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
769 */
298
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
770 static char *stringify(struct token *tl)
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
771 {
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
772 struct strbuf *s;
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
773 int ws = 0;
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
774
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
775 s = strbuf_new();
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
776 strbuf_add(s, '"');
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
777
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
778 while (tl && tl -> ttype == TOK_WSPACE)
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
779 tl = tl -> next;
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
780
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
781 for (; tl; tl = tl -> next)
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
782 {
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
783 if (tl -> ttype == TOK_WSPACE)
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
784 {
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
785 ws = 1;
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
786 continue;
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
787 }
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
788 if (ws)
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
789 {
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
790 strbuf_add(s, ' ');
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
791 }
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
792 for (ws = 0; tl -> strval[ws]; ws++)
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
793 {
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
794 if (tl -> ttype == TOK_STRING || tl -> ttype == TOK_CHR_LIT)
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
795 {
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
796 if (tl -> strval[ws] == '"' || tl -> strval[ws] == '\\')
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
797 strbuf_add(s, '\\');
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
798 }
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
799 }
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
800 ws = 0;
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
801 }
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
802
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
803 strbuf_add(s, '"');
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
804 return strbuf_end(s);
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
805 }
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
806
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
807 /* return list to tokens as a result of ## expansion */
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
808 static struct token *paste_tokens(struct preproc_info *pp, struct symtab_e *s, struct token **arglist, struct token *t1, struct token *t2)
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
809 {
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
810 struct token *rl = NULL, *rlt;
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
811 struct token *s1, *s2;
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
812 struct token *ws;
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
813 int i;
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
814 char *tstr;
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
815
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
816 if (t1 -> ttype == TOK_IDENT)
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
817 {
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
818 if (strcmp(t1 -> strval, "__VA_ARGS__") == 0)
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
819 {
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
820 i = s -> nargs;
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
821 }
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
822 else
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
823 {
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
824 for (i = 0; i < s -> nargs; i++)
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
825 {
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
826 if (strcmp(s -> params[i], t1 -> strval) == 0)
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
827 break;
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
828 }
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
829 }
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
830 if ((i == s -> nargs) && !(s -> vargs))
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
831 {
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
832 s1 = token_dup(t1);
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
833 }
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
834 else
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
835 {
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
836 /* find last non-whitespace token */
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
837 ws = NULL;
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
838 for (t1 = s -> tl; t1; t1 = t1 -> next)
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
839 {
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
840 if (t1 -> ttype != TOK_WSPACE)
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
841 ws = t1;
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
842 }
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
843 if (!ws)
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
844 {
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
845 s1 = NULL;
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
846 }
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
847 else
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
848 {
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
849 if (ws != s -> tl)
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
850 {
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
851 /* output extra tokens */
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
852 for (t1 = s -> tl; t1 -> next != ws; t1 = t1 -> next)
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
853 {
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
854 if (!rl)
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
855 {
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
856 rl = token_dup(t1);
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
857 rlt = rl;
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
858 }
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
859 else
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
860 {
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
861 rlt -> next = token_dup(t1);
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
862 rlt = rlt -> next;
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
863 }
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
864 }
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
865 }
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
866 s1 = token_dup(ws);
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
867 }
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
868 }
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
869 }
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
870 else
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
871 {
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
872 s1 = token_dup(t1);
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
873 }
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
874 if (t2 -> ttype == TOK_IDENT)
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
875 {
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
876 if (strcmp(t1 -> strval, "__VA_ARGS__") == 0)
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
877 {
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
878 i = s -> nargs;
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
879 }
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
880 else
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
881 {
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
882 for (i = 0; i < s -> nargs; i++)
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
883 {
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
884 if (strcmp(s -> params[i], t1 -> strval) == 0)
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
885 break;
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
886 }
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
887 }
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
888 if ((i == s -> nargs) && !(s -> vargs))
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
889 {
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
890 s2 = token_dup(t2);
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
891 t2 = NULL;
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
892 }
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
893 else
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
894 {
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
895 /* find last non-whitespace token */
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
896 ws = NULL;
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
897 for (t2 = s -> tl; t2; t2 = t2 -> next)
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
898 {
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
899 if (t2 -> ttype != TOK_WSPACE)
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
900 {
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
901 ws = t2;
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
902 t2 = t2 -> next;
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
903 break;
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
904 }
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
905 }
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
906 if (!ws)
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
907 {
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
908 s2 = NULL;
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
909 }
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
910 else
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
911 {
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
912 s2 = token_dup(ws);
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
913 }
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
914 }
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
915 }
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
916 else
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
917 {
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
918 s2 = token_dup(t2);
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
919 }
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
920
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
921 /* here, s1 is NULL if no left operand or a duplicated token for the actual left operand */
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
922 /* here, s2 is NULL if no right operand or a duplicated token for the actual right operand */
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
923 /* here, t2 points to a possibly empty list of extra tokens to output after the concatenated tokens */
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
924 /* here, rl,rlt is a possibly non-empty list of tokens preceding the concatenation */
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
925
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
926 /* tokens combine if the combination exactly matches "combinelist", in which case the string values are
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
927 concatenated and the new token type is used to create a new token. If the tokens do not combine,
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
928 s1 and s2 are returned in sequence. */
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
929
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
930 if (!s1 && s2)
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
931 {
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
932 if (!rl)
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
933 rl = s2;
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
934 else
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
935 rlt -> next = s2;
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
936 rlt = s2;
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
937 }
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
938 else if (s1 && !s2)
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
939 {
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
940 if (!rl)
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
941 rl = s1;
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
942 else
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
943 rlt -> next = s1;
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
944 rlt = s1;
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
945 }
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
946 else if (s1 && s2)
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
947 {
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
948 tstr = lw_alloc(strlen(s1 -> strval) + strlen(s2 -> strval) + 1);
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
949 strcpy(tstr, s1 -> strval);
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
950 strcat(tstr, s2 -> strval);
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
951 /* now try to lex the string */
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
952 pp -> lexstr = tstr;
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
953 pp -> lexstrloc = 0;
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
954 t1 = preproc_lex_next_token(pp);
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
955 if (pp -> lexstr[pp -> lexstrloc])
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
956 {
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
957 // doesn't make a new token - pass through the original two
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
958 if (!rl)
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
959 rl = s1;
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
960 else
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
961 rlt -> next = s1;
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
962 s1 -> next = s2;
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
963 rlt = s2;
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
964 }
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
965 else
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
966 {
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
967 // does make a new token
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
968 t1 -> fn = s1 -> fn;
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
969 t1 -> column = s1 -> column;
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
970 t1 -> lineno = s1 -> lineno;
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
971 if (!rl)
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
972 rl = t1;
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
973 else
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
974 rlt -> next = t1;
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
975 rlt = t1;
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
976 }
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
977 lw_free(tstr);
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
978 pp -> lexstr = NULL;
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
979 }
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
980
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
981 /* add in any extra tokens */
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
982 while (t2)
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
983 {
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
984 if (!rl)
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
985 {
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
986 rl = token_dup(t2);
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
987 rlt = rl;
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
988 }
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
989 else
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
990 {
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
991 rlt -> next = token_dup(t2);
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
992 rlt = rlt -> next;
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
993 }
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
994 t2 = t2 -> next;
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
995 }
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
996
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
997 return rl;
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
998 }
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
999
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
1000
296
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1001 static int expand_macro(struct preproc_info *pp, char *mname)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1002 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1003 struct symtab_e *s;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1004 struct token *t, *t2, *t3;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1005 struct token **arglist = NULL;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1006 int nargs = 0;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1007 struct expand_e *e;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1008 struct token **exparglist = NULL;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1009 int i;
297
310df72c641d Handle () surrounding macro args on invocation
William Astle <lost@l-w.ca>
parents: 296
diff changeset
1010 int pcount;
298
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
1011 char *tstr;
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
1012
296
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1013 s = symtab_find(pp, mname);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1014 if (!s)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1015 return 0;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1016
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1017 for (e = pp -> expand_list; e; e = e -> next)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1018 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1019 /* don't expand if we're already expanding the same macro */
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1020 if (e -> s == s)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1021 return 0;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1022 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1023
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1024 if (s -> nargs == -1)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1025 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1026 /* short circuit NULL expansion */
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1027 if (s -> tl == NULL)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1028 return 1;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1029
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1030 goto expandmacro;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1031 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1032
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1033 // look for opening paren after optional whitespace
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1034 t2 = NULL;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1035 t = NULL;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1036 for (;;)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1037 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1038 t = preproc_next_token(pp);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1039 if (t -> ttype != TOK_WSPACE && t -> ttype != TOK_EOL)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1040 break;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1041 t -> next = t2;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1042 t2 = t2;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1043 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1044 if (t -> ttype != TOK_OPAREN)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1045 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1046 // not a function-like invocation
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1047 while (t2)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1048 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1049 t = t2 -> next;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1050 preproc_unget_token(pp, t2);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1051 t2 = t;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1052 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1053 return 0;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1054 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1055
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1056 // parse parameters here
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1057 t = preproc_next_token_nws(pp);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1058 nargs = 1;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1059 arglist = lw_alloc(sizeof(struct token *));
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1060 arglist[0] = NULL;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1061 t2 = NULL;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1062
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1063 while (t -> ttype != TOK_CPAREN)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1064 {
297
310df72c641d Handle () surrounding macro args on invocation
William Astle <lost@l-w.ca>
parents: 296
diff changeset
1065 pcount = 0;
296
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1066 if (t -> ttype == TOK_EOF)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1067 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1068 preproc_throw_error(pp, "Unexpected EOF in macro call");
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1069 break;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1070 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1071 if (t -> ttype == TOK_EOL)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1072 continue;
297
310df72c641d Handle () surrounding macro args on invocation
William Astle <lost@l-w.ca>
parents: 296
diff changeset
1073 if (t -> ttype == TOK_OPAREN)
310df72c641d Handle () surrounding macro args on invocation
William Astle <lost@l-w.ca>
parents: 296
diff changeset
1074 pcount++;
310df72c641d Handle () surrounding macro args on invocation
William Astle <lost@l-w.ca>
parents: 296
diff changeset
1075 else if (t -> ttype == TOK_CPAREN && pcount)
310df72c641d Handle () surrounding macro args on invocation
William Astle <lost@l-w.ca>
parents: 296
diff changeset
1076 pcount--;
310df72c641d Handle () surrounding macro args on invocation
William Astle <lost@l-w.ca>
parents: 296
diff changeset
1077 if (t -> ttype == TOK_COMMA && pcount == 0)
296
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1078 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1079 if (!(s -> vargs) || (nargs > s -> nargs))
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1080 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1081 nargs++;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1082 arglist = lw_realloc(arglist, sizeof(struct token *) * nargs);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1083 arglist[nargs - 1] = NULL;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1084 t2 = NULL;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1085 continue;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1086 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1087 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1088 if (t2)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1089 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1090 t2 -> next = token_dup(t);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1091 t2 = t2 -> next;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1092 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1093 else
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1094 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1095 t2 = token_dup(t);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1096 arglist[nargs - 1] = t2;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1097 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1098 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1099
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1100 if (s -> vargs)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1101 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1102 if (nargs <= s -> nargs)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1103 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1104 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
1105 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1106 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1107 else
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1108 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1109 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
1110 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1111 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
1112 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1113 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1114
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1115 /* now calculate the pre-expansions of the arguments */
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1116 exparglist = lw_alloc(nargs);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1117 for (i = 0; i < nargs; i++)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1118 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1119 t2 = NULL;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1120 exparglist[i] = NULL;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1121 // NOTE: do nothing if empty argument
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1122 if (arglist[i] == NULL)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1123 continue;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1124 pp -> sourcelist = arglist[i];
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1125 for (;;)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1126 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1127 t = preproc_next_processed_token(pp);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1128 if (t -> ttype == TOK_EOF)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1129 break;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1130 if (t2)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1131 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1132 t2 -> next = token_dup(t);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1133 t2 = t2 -> next;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1134 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1135 else
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1136 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1137 t2 = token_dup(t);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1138 exparglist[i] = t2;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1139 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1140 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1141 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1142
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1143 expandmacro:
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1144 t2 = NULL;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1145 t3 = NULL;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1146
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1147 for (t = s -> tl; t; t = t -> next)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1148 {
298
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
1149 again:
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
1150 if (t -> ttype != TOK_WSPACE && t -> next)
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
1151 {
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
1152 struct token *ct1, *ct2;
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
1153
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
1154 for (ct1 = t -> next; ct1 && ct1 -> ttype == TOK_WSPACE; ct1 = ct1 -> next)
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
1155 {
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
1156 if (ct1 -> ttype == TOK_DBLHASH)
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
1157 {
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
1158 // possible concatenation here
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
1159 for (ct2 = ct1 -> next; ct2 && ct2 -> ttype == TOK_WSPACE; ct2 = ct2 -> next)
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
1160 /* do nothing */ ;
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
1161 if (ct2)
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
1162 {
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
1163 // we have concatenation here so we paste str1 and str2 together and see what we get
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
1164 // if we get NULL, the past didn't make a valid token
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
1165 ct1 = paste_tokens(pp, s, arglist, t, ct2);
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
1166 if (ct1)
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
1167 {
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
1168 if (t2)
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
1169 {
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
1170 t2 -> next = ct1;
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
1171 }
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
1172 else
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
1173 {
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
1174 t3 = ct1;
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
1175 }
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
1176 for (t2 = ct1; t2 -> next; t2 = t2 -> next)
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
1177 /* do nothing */ ;
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
1178
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
1179 /* because of the level of control structures, move to next token and restart loop */
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
1180 t = ct2 -> next;
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
1181 goto again;
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
1182 }
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
1183 goto nopaste;
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
1184 }
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
1185 }
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
1186 }
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
1187 }
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
1188
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
1189 nopaste:
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
1190 if (t -> ttype == TOK_HASH)
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
1191 {
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
1192 if (t -> next && t -> next -> ttype == TOK_IDENT)
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
1193 {
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
1194 if (strcmp(t -> next -> strval, "__VA_ARGS__") == 0)
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
1195 {
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
1196 i = nargs;
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
1197 }
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
1198 else
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
1199 {
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
1200 for (i = 0; i < nargs; i++)
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
1201 {
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
1202 if (strcmp(t -> next -> strval, s -> params[i]) == 0)
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
1203 break;
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
1204 }
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
1205 }
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
1206 if (!((i == s -> nargs) && !(s -> vargs)))
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
1207 {
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
1208 // we have a stringification here
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
1209 t = t -> next;
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
1210 tstr = stringify(arglist[i]);
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
1211 if (t2)
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
1212 {
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
1213 t2 = token_create(TOK_STRING, tstr, t -> lineno, t -> column, t -> fn);
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
1214 t2 = t2 -> next;
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
1215 }
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
1216 else
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
1217 {
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
1218 t3 = token_create(TOK_STRING, tstr, t -> lineno, t -> column, t -> fn);
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
1219 t2 = t3;
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
1220 }
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
1221 lw_free(tstr);
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
1222 continue;
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
1223 }
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
1224 }
6112c67728ba Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents: 297
diff changeset
1225 }
296
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1226 if (t -> ttype == TOK_IDENT)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1227 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1228 /* identifiers might need expansion to arguments */
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1229 if (strcmp(t -> strval, "__VA_ARGS__") == 0)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1230 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1231 i = s -> nargs;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1232 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1233 else
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1234 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1235 for (i = 0; i < nargs; i++)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1236 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1237 if (strcmp(t -> strval, s -> params[i]) == 0)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1238 break;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1239 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1240 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1241 if ((i == s -> nargs) && !(s -> vargs))
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1242 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1243 struct token *te;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1244 // expand argument
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1245 for (te = exparglist[i]; te; te = te -> next)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1246 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1247 if (t2)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1248 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1249 t2 -> next = token_dup(te);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1250 t2 = t2 -> next;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1251 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1252 else
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1253 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1254 t3 = token_dup(te);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1255 t2 = t2;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1256 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1257 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1258 continue;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1259 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1260 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1261 if (t2)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1262 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1263 t2 -> next = token_dup(t);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1264 t2 = t2 -> next;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1265 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1266 else
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1267 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1268 t3 = token_dup(t);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1269 t2 = t3;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1270 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1271 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1272
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1273 /* 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
1274 expanded to nothing, no need to create an expansion record or
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1275 put anything into the input queue */
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1276 if (t3)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1277 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1278 t2 -> next = token_create(TOK_ENDEXPAND, "", -1, -1, "");
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1279 t2 -> next -> next = pp -> tokqueue;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1280 pp -> tokqueue = t3;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1281
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1282 /* set up expansion record */
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1283 e = lw_alloc(sizeof(struct expand_e));
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1284 e -> next = pp -> expand_list;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1285 pp -> expand_list = e;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1286 e -> s = s;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1287 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1288
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1289 /* now clean up */
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1290 for (i = 0; i < nargs; i++)
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1291 {
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1292 lw_free(arglist[i]);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1293 lw_free(exparglist[i]);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1294 }
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1295 lw_free(arglist);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1296 lw_free(exparglist);
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1297
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1298 return 1;
83fcc1ed6ad6 Checkpoint lwcc development
William Astle <lost@l-w.ca>
parents:
diff changeset
1299 }