Mercurial > hg > index.cgi
comparison lwcc/cc-parse.c @ 506:7e8298f7bc0a
Add basic syntax for typecasting
Add parser support for type casts. This current scheme handles only integer
types.
Also include parenthesis grouping in expressions.
author | William Astle <lost@l-w.ca> |
---|---|
date | Sun, 27 Oct 2019 12:06:01 -0600 |
parents | 14a40f8bb4eb |
children |
comparison
equal
deleted
inserted
replaced
505:59b8c8b15bd4 | 506:7e8298f7bc0a |
---|---|
169 | 169 |
170 } | 170 } |
171 | 171 |
172 node_t *parse_expr_real(struct parser_state *ps, int prec); | 172 node_t *parse_expr_real(struct parser_state *ps, int prec); |
173 | 173 |
174 // parse an elementary type (int, etc.) | |
175 node_t *parse_elem_type(struct parser_state *ps) | |
176 { | |
177 int sgn = -1; | |
178 int nt = -1; | |
179 int nn = 1; | |
180 | |
181 if (ps -> curtok -> ttype == TOK_KW_SIGNED) | |
182 { | |
183 sgn = 1; | |
184 parse_next(ps); | |
185 } | |
186 else if (ps -> curtok -> ttype == TOK_KW_UNSIGNED) | |
187 { | |
188 sgn = 0; | |
189 parse_next(ps); | |
190 } | |
191 | |
192 switch (ps -> curtok -> ttype) | |
193 { | |
194 // NOTE: char is unsigned by default | |
195 case TOK_KW_CHAR: | |
196 if (sgn == -1 || sgn == 0) | |
197 nt = NODE_TYPE_UCHAR; | |
198 else | |
199 nt = NODE_TYPE_CHAR; | |
200 break; | |
201 | |
202 case TOK_KW_SHORT: | |
203 nt = sgn ? NODE_TYPE_SHORT : NODE_TYPE_USHORT; | |
204 break; | |
205 | |
206 case TOK_KW_INT: | |
207 nt = sgn ? NODE_TYPE_INT : NODE_TYPE_UINT; | |
208 break; | |
209 | |
210 case TOK_KW_LONG: | |
211 parse_next(ps); | |
212 if (ps -> curtok -> ttype == TOK_KW_LONG) | |
213 { | |
214 nt = sgn ? NODE_TYPE_LONGLONG : NODE_TYPE_ULONGLONG; | |
215 break; | |
216 } | |
217 nn = 0; | |
218 nt = sgn ? NODE_TYPE_LONG : NODE_TYPE_ULONG; | |
219 break; | |
220 | |
221 } | |
222 if (nt == -1) | |
223 { | |
224 if (sgn == -1) | |
225 { | |
226 return NULL; | |
227 } | |
228 else | |
229 { | |
230 nt = sgn ? NODE_TYPE_INT : NODE_TYPE_UINT; | |
231 } | |
232 } | |
233 else if (nn) | |
234 { | |
235 parse_next(ps); | |
236 } | |
237 return node_create(nt); | |
238 } | |
239 | |
240 // if ident is non-zero, accept an identifier as part of the type; otherwise | |
241 // do not accept an identifier; currently a stub | |
242 node_t *parse_type(struct parser_state *ps, int ident) | |
243 { | |
244 node_t *rv; | |
245 | |
246 // see if we have an elementary type | |
247 rv = parse_elem_type(ps); | |
248 | |
249 // look for "struct", etc. | |
250 | |
251 // look for pointer indicator(s) | |
252 | |
253 // look for identifier if wanted/allowed | |
254 | |
255 // look for array indicator or function parameter list | |
256 return rv; | |
257 } | |
258 | |
174 node_t *parse_term_real(struct parser_state *ps) | 259 node_t *parse_term_real(struct parser_state *ps) |
175 { | 260 { |
176 node_t *rv; | 261 node_t *rv, *rv2; |
177 | 262 |
178 switch (ps -> curtok -> ttype) | 263 switch (ps -> curtok -> ttype) |
179 { | 264 { |
180 case TOK_CONST_INT: | 265 case TOK_CONST_INT: |
181 rv = node_create(NODE_CONST_INT, ps -> curtok -> strval); | 266 rv = node_create(NODE_CONST_INT, ps -> curtok -> strval); |
267 parse_next(ps); | |
268 return rv; | |
269 | |
270 // opening paren: either grouping or type cast | |
271 case TOK_OPAREN: | |
272 parse_next(ps); | |
273 // parse a type without an identifier | |
274 rv2 = parse_type(ps, 0); | |
275 if (rv2) | |
276 { | |
277 if (ps -> curtok -> ttype != TOK_CPAREN) | |
278 { | |
279 node_destroy(rv2); | |
280 parse_generr(ps, "missing ) on type cast"); | |
281 return NULL; | |
282 } | |
283 parse_next(ps); | |
284 // detect C99 compound literal here | |
285 rv = parse_expr_real(ps, 175); | |
286 if (!rv) | |
287 { | |
288 node_destroy(rv); | |
289 return NULL; | |
290 } | |
291 return node_create(NODE_TYPECAST, rv2, rv); | |
292 } | |
293 // grouping | |
294 rv = parse_expr_real(ps, 0); | |
295 if (ps -> curtok -> ttype != TOK_CPAREN) | |
296 { | |
297 node_destroy(rv); | |
298 parse_generr(ps, "missing ) on expression grouping"); | |
299 return NULL; | |
300 } | |
182 parse_next(ps); | 301 parse_next(ps); |
183 return rv; | 302 return rv; |
184 } | 303 } |
185 | 304 |
186 parse_generr(ps, "term"); | 305 parse_generr(ps, "term"); |