]> pd.if.org Git - lice/blob - parse.c
autocommit for files dated 2014-11-17 20:15:26
[lice] / parse.c
1 #include <ctype.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <limits.h>
5
6 #include "lice.h"
7 #include "lexer.h"
8 #include "conv.h"
9 #include "init.h"
10 #include "parse.h"
11 #include "opt.h"
12
13 static ast_t       *parse_expression(void);
14 static ast_t       *parse_expression_postfix(void);
15 static ast_t       *parse_expression_multiplicative(void);
16 static ast_t       *parse_expression_conditional(void);
17 static ast_t       *parse_expression_cast(void);
18 static data_type_t *parse_expression_cast_type(void);
19 static ast_t       *parse_expression_unary(void);
20 static ast_t       *parse_expression_comma(void);
21
22 static ast_t       *parse_statement_compound(void);
23 static void         parse_statement_declaration(list_t *);
24 static ast_t       *parse_statement(void);
25
26
27 static data_type_t *parse_declaration_specification(storage_t *);
28 static data_type_t *parse_declarator(char **, data_type_t *, list_t *, cdecl_t);
29 static void         parse_declaration(list_t *, ast_t *(*)(data_type_t *, char *));
30
31 static data_type_t *parse_function_parameter(char **, bool);
32 static data_type_t *parse_function_parameters(list_t *, data_type_t *);
33
34
35 table_t *parse_typedefs = &SENTINEL_TABLE;
36
37 static bool parse_type_check(lexer_token_t *token);
38
39 static void parse_semantic_lvalue(ast_t *ast) {
40     switch (ast->type) {
41         case AST_TYPE_VAR_LOCAL:
42         case AST_TYPE_VAR_GLOBAL:
43         case AST_TYPE_DEREFERENCE:
44         case AST_TYPE_STRUCT:
45             return;
46     }
47     compile_error("expected lvalue, `%s' isn't a valid lvalue", ast_string(ast));
48 }
49
50 static void parse_semantic_notvoid(data_type_t *type) {
51     if (type->type == TYPE_VOID)
52         compile_error("void not allowed in expression");
53 }
54
55 void parse_expect(char punct) {
56     lexer_token_t *token = lexer_next();
57     if (!lexer_ispunct(token, punct))
58         compile_error("expected `%c`, got %s instead", punct, lexer_token_string(token));
59 }
60
61 void parse_semantic_assignable(data_type_t *to, data_type_t *from) {
62     from = ast_array_convert(from);
63     if ((conv_capable(to)   || to->type   == TYPE_POINTER) &&
64         (conv_capable(from) || from->type == TYPE_POINTER)) {
65
66         return;
67     }
68
69     if (ast_struct_compare(to, from))
70         return;
71
72     compile_error("incompatible types '%s' and '%s' in assignment", ast_type_string(to), ast_type_string(from));
73 }
74
75 static bool parse_identifer_check(lexer_token_t *token, const char *identifier) {
76     return token->type == LEXER_TOKEN_IDENTIFIER && !strcmp(token->string, identifier);
77 }
78
79 long parse_evaluate(ast_t *ast);
80 int parse_evaluate_offsetof(ast_t *ast, int offset) {
81     if (ast->type == AST_TYPE_STRUCT)
82         return parse_evaluate_offsetof(ast->structure, ast->ctype->offset + offset);
83     return parse_evaluate(ast) + offset;
84 }
85
86 long parse_evaluate(ast_t *ast) {
87     long cond;
88
89     switch (ast->type) {
90         case AST_TYPE_LITERAL:
91             if (ast_type_isinteger(ast->ctype))
92                 return ast->integer;
93             compile_error("not a valid integer constant expression `%s'", ast_string(ast));
94             break;
95
96         case '+':             return parse_evaluate(ast->left) +  parse_evaluate(ast->right);
97         case '-':             return parse_evaluate(ast->left) -  parse_evaluate(ast->right);
98         case '*':             return parse_evaluate(ast->left) *  parse_evaluate(ast->right);
99         case '/':             return parse_evaluate(ast->left) /  parse_evaluate(ast->right);
100         case '<':             return parse_evaluate(ast->left) <  parse_evaluate(ast->right);
101         case '>':             return parse_evaluate(ast->left) >  parse_evaluate(ast->right);
102         case '^':             return parse_evaluate(ast->left) ^  parse_evaluate(ast->right);
103         case '%':             return parse_evaluate(ast->left) %  parse_evaluate(ast->right);
104         case '|':             return parse_evaluate(ast->left) |  parse_evaluate(ast->right);
105
106         case AST_TYPE_AND:    return parse_evaluate(ast->left) && parse_evaluate(ast->right);
107         case AST_TYPE_OR:     return parse_evaluate(ast->left) || parse_evaluate(ast->right);
108         case AST_TYPE_EQUAL:  return parse_evaluate(ast->left) == parse_evaluate(ast->right);
109         case AST_TYPE_LEQUAL: return parse_evaluate(ast->left) <= parse_evaluate(ast->right);
110         case AST_TYPE_GEQUAL: return parse_evaluate(ast->left) >= parse_evaluate(ast->right);
111         case AST_TYPE_NEQUAL: return parse_evaluate(ast->left) != parse_evaluate(ast->right);
112         case AST_TYPE_LSHIFT: return parse_evaluate(ast->left) << parse_evaluate(ast->right);
113         case AST_TYPE_RSHIFT: return parse_evaluate(ast->left) >> parse_evaluate(ast->right);
114
115
116         /* Deal with unary operations differently */
117         case '!':                        return !parse_evaluate(ast->unary.operand);
118         case '~':                        return ~parse_evaluate(ast->unary.operand);
119         case AST_TYPE_NEGATE:            return -parse_evaluate(ast->unary.operand);
120         case AST_TYPE_EXPRESSION_CAST:   return  parse_evaluate(ast->unary.operand);
121
122         /* Branches too */
123         case AST_TYPE_EXPRESSION_TERNARY:
124             cond = parse_evaluate(ast->ifstmt.cond);
125             if (cond)
126                 return ast->ifstmt.then ? parse_evaluate(ast->ifstmt.cond) : cond;
127             return parse_evaluate(ast->ifstmt.last);
128
129         /* Deal with logical right shift specifically */
130         case AST_TYPE_LRSHIFT:
131             return ((unsigned long)parse_evaluate(ast->left)) >> parse_evaluate(ast->right);
132
133         case AST_TYPE_CONVERT:
134             return parse_evaluate(ast->unary.operand);
135
136         /*
137          * Allow constant evaluation for things like offsetof, although
138          * we could just implement __builtin_offsetof, this works easier
139          * and also allows the existing idiom to work.
140          */
141         case AST_TYPE_ADDRESS:
142             if (ast->unary.operand->type == AST_TYPE_STRUCT)
143                 return parse_evaluate_offsetof(ast->unary.operand, 0);
144             goto error;
145
146         case AST_TYPE_DEREFERENCE:
147             if (ast->unary.operand->ctype->type == TYPE_POINTER)
148                 return parse_evaluate(ast->unary.operand);
149             goto error;
150
151         default:
152         error:
153             compile_error("not a valid integer constant expression `%s'", ast_string(ast));
154     }
155     return -1;
156 }
157
158 bool parse_next(int ch) {
159     lexer_token_t *token = lexer_next();
160     if (lexer_ispunct(token, ch))
161         return true;
162     lexer_unget(token);
163     return false;
164 }
165
166 static list_t *parse_function_args(list_t *parameters) {
167     list_t          *list = list_create();
168     list_iterator_t *it   = list_iterator(parameters);
169     for (;;) {
170         if (parse_next(')'))
171             break;
172         ast_t       *arg  = parse_expression_assignment();
173         data_type_t *type = list_iterator_next(it);
174
175         if (!type) {
176             type = ast_type_isfloating(arg->ctype)
177                         ? ast_data_table[AST_DATA_DOUBLE]
178                         : ast_type_isinteger(arg->ctype)
179                             ? ast_data_table[AST_DATA_INT]
180                             : arg->ctype;
181         }
182
183         // todo semantic check
184         parse_semantic_assignable(ast_array_convert(type), ast_array_convert(arg->ctype));
185
186         if (type->type != arg->ctype->type)
187             arg = ast_type_convert(type, arg);
188
189         list_push(list, arg);
190
191         lexer_token_t *token = lexer_next();
192         if (lexer_ispunct(token, ')'))
193             break;
194         if (!lexer_ispunct(token, ','))
195             compile_error("unexpected token `%s'", lexer_token_string(token));
196     }
197     return list;
198 }
199
200 static ast_t *parse_va_start(void) {
201     ast_t *ap = parse_expression_assignment();
202     parse_expect(')');
203     return ast_va_start(ap);
204 }
205
206 static ast_t *parse_va_arg(void) {
207     ast_t *ap = parse_expression_assignment();
208     parse_expect(',');
209     data_type_t *type = parse_expression_cast_type();
210     parse_expect(')');
211     return ast_va_arg(type, ap);
212 }
213
214 static ast_t *parse_function_call(char *name, ast_t *function) {
215     if (!strcmp(name, "__builtin_va_start"))
216         return parse_va_start();
217     if (!strcmp(name, "__builtin_va_arg"))
218         return parse_va_arg();
219
220     if (function) {
221         data_type_t *declaration = function->ctype;
222         if (declaration->type != TYPE_FUNCTION)
223             compile_error("expected a function name, `%s' isn't a function", name);
224         list_t *list = parse_function_args(declaration->parameters);
225         return ast_call(declaration, name, list);
226     }
227     compile_warn("implicit declaration of function ‘%s’", name);
228     list_t *list = parse_function_args(&SENTINEL_LIST);
229     return ast_call(ast_prototype(ast_data_table[AST_DATA_INT], list_create(), true), name, list);
230 }
231
232 static ast_t *parse_function_pointer_call(ast_t *function) {
233     list_t *list = parse_function_args(function->ctype->pointer->parameters);
234     return ast_pointercall(function, list);
235 }
236
237 static ast_t *parse_generic(char *name) {
238     ast_t *ast = table_find(ast_localenv ? ast_localenv : ast_globalenv, name);
239
240     if (!ast || ast->ctype->type == TYPE_FUNCTION)
241         return ast_designator(name, ast);
242
243     return ast;
244 }
245
246 static ast_t *parse_number_integer(char *string) {
247     char *p    = string;
248     int   base = 10;
249
250     if (!strncasecmp(string, "0x", 2)) {
251         base = 16;
252         p++;
253         p++;
254     } else if (!strncasecmp(string, "0b", 2)){
255         if (!opt_extension_test(EXTENSION_BINARYCONSTANTS))
256             compile_error("binary constants only supported in -std=lice or -std=gnuc");
257         base = 2;
258         p++;
259         p++;
260     } else if (string[0] == '0' && string[1] != '\0') {
261         base = 8;
262         p++;
263     }
264
265     char *digits = p;
266     while (isxdigit(*p)) {
267         if (base == 10 && isalpha(*p))
268             compile_error("invalid character in decimal literal");
269         if (base == 8 && !('0' <= *p && *p <= '7'))
270             compile_error("invalid character in octal literal");
271         if (base == 2 && (*p != '0' && *p != '1'))
272             compile_error("invalid character in binary literal");
273         p++;
274     }
275
276     if (!strcasecmp(p, "l"))
277         return ast_new_integer(ast_data_table[AST_DATA_LONG], strtol(string, NULL, base));
278     if (!strcasecmp(p, "ul") || !strcasecmp(p, "lu") || !strcasecmp(p, "u"))
279         return ast_new_integer(ast_data_table[AST_DATA_ULONG], strtoul(string, NULL, base));
280     if (!strcasecmp(p, "ll"))
281         return ast_new_integer(ast_data_table[AST_DATA_LLONG], strtoll(string, NULL, base));
282     if (!strcasecmp(p, "ull") || !strcasecmp(p, "llu"))
283         return ast_new_integer(ast_data_table[AST_DATA_ULLONG], strtoull(string, NULL, base));
284     if (*p != '\0')
285         compile_error("invalid suffix for literal");
286
287     long value = strtol(digits, NULL, base);
288     return (value & ~(long)UINT_MAX)
289                 ? ast_new_integer(ast_data_table[AST_DATA_LONG], value)
290                 : ast_new_integer(ast_data_table[AST_DATA_INT], value);
291 }
292
293 static ast_t *parse_number_floating(char *string) {
294     char *p = string;
295     char *end;
296
297     while (p[1])
298         p++;
299
300     ast_t *ast;
301     if (*p == 'l' || *p == 'L')
302         ast = ast_new_floating(ast_data_table[AST_DATA_LDOUBLE], strtold(string, &end));
303     else if (*p == 'f' || *p == 'F')
304         ast = ast_new_floating(ast_data_table[AST_DATA_FLOAT], strtof(string, &end));
305     else {
306         ast = ast_new_floating(ast_data_table[AST_DATA_DOUBLE], strtod(string, &end));
307         p++;
308     }
309
310     if (end != p)
311         compile_error("malformatted float literal");
312
313     return ast;
314 }
315
316 static ast_t *parse_number(char *string) {
317     return strpbrk(string, ".pP") ||
318                 /*
319                  * 0xe.. is integer type, sadly it's hard to check for that
320                  * without additonal logic.
321                  */
322                 (strncasecmp(string, "0x", 2) && strpbrk(string, "eE"))
323                     ? parse_number_floating(string)
324                     : parse_number_integer(string);
325 }
326
327 static int parse_operation_reclassify(int punct) {
328     switch (punct) {
329         case LEXER_TOKEN_LSHIFT: return AST_TYPE_LSHIFT;
330         case LEXER_TOKEN_RSHIFT: return AST_TYPE_RSHIFT;
331         case LEXER_TOKEN_EQUAL:  return AST_TYPE_EQUAL;
332         case LEXER_TOKEN_GEQUAL: return AST_TYPE_GEQUAL;
333         case LEXER_TOKEN_LEQUAL: return AST_TYPE_LEQUAL;
334         case LEXER_TOKEN_NEQUAL: return AST_TYPE_NEQUAL;
335         case LEXER_TOKEN_AND:    return AST_TYPE_AND;
336         case LEXER_TOKEN_OR:     return AST_TYPE_OR;
337         default:
338             break;
339     }
340     return punct;
341 }
342
343 static int parse_operation_compound_operator(lexer_token_t *token) {
344     if (token->type != LEXER_TOKEN_PUNCT)
345         return 0;
346
347     switch (token->punct) {
348         case LEXER_TOKEN_COMPOUND_RSHIFT: return LEXER_TOKEN_RSHIFT;
349         case LEXER_TOKEN_COMPOUND_LSHIFT: return LEXER_TOKEN_LSHIFT;
350         case LEXER_TOKEN_COMPOUND_ADD:    return '+';
351         case LEXER_TOKEN_COMPOUND_AND:    return '&';
352         case LEXER_TOKEN_COMPOUND_DIV:    return '/';
353         case LEXER_TOKEN_COMPOUND_MOD:    return '%';
354         case LEXER_TOKEN_COMPOUND_MUL:    return '*';
355         case LEXER_TOKEN_COMPOUND_OR:     return '|';
356         case LEXER_TOKEN_COMPOUND_SUB:    return '-';
357         case LEXER_TOKEN_COMPOUND_XOR:    return '^';
358         default:
359             return 0;
360     }
361     return -1;
362 }
363
364 static ast_t *parse_expression_statement(void) {
365     ast_t *ast = parse_statement_compound();
366     parse_expect(')');
367     data_type_t *type = ast_data_table[AST_DATA_VOID];
368     if (list_length(ast->compound) > 0) {
369         ast_t *last = list_tail(ast->compound);
370         if (last)
371             type = last->ctype;
372     }
373     ast->ctype = type;
374     return ast;
375 }
376
377 static ast_t *parse_expression_primary(void) {
378     lexer_token_t *token;
379
380     if (!(token = lexer_next()))
381         return NULL;
382
383     if (lexer_ispunct(token, '(')) {
384
385         if (parse_next('{')) {
386             if (!opt_extension_test(EXTENSION_STATEMENTEXPRS))
387                 compile_error("statement expressions only supported in -std=gnuc or -std=licec");
388             return parse_expression_statement();
389         }
390
391         ast_t *ast = parse_expression();
392         parse_expect(')');
393         return ast;
394     }
395
396     switch (token->type) {
397         case LEXER_TOKEN_IDENTIFIER:
398             return parse_generic(token->string);
399         case LEXER_TOKEN_NUMBER:
400             return parse_number(token->string);
401         case LEXER_TOKEN_CHAR:
402             return ast_new_integer(ast_data_table[AST_DATA_INT], token->character);
403         case LEXER_TOKEN_STRING:
404             return ast_new_string(token->string);
405         case LEXER_TOKEN_PUNCT:
406             lexer_unget(token);
407             return NULL;
408         default:
409             break;
410     }
411
412     compile_ice("parse_expression_primary");
413     return NULL;
414 }
415
416 static ast_t *parse_expression_subscript(ast_t *ast) {
417     ast_t *subscript = parse_expression();
418     if (!subscript)
419         compile_error("expected subscript operand");
420     parse_expect(']');
421     ast_t *node = conv_usual('+', ast, subscript);
422     return ast_new_unary(AST_TYPE_DEREFERENCE, node->ctype->pointer, node);
423 }
424
425 static data_type_t *parse_sizeof_operand(void) {
426     lexer_token_t *token = lexer_next();
427
428     if (lexer_ispunct(token, '(') && parse_type_check(lexer_peek())) {
429         data_type_t *next = parse_function_parameter(NULL, true);
430         parse_expect(')');
431         return next;
432     }
433
434     lexer_unget(token);
435     ast_t *expression = parse_expression_unary();
436
437     if (opt_std_test(STANDARD_GNUC) || opt_std_test(STANDARD_LICEC)) {
438         if (expression->type == AST_TYPE_DESIGNATOR)
439             return expression->function.call.functionpointer->ctype;
440         return expression->ctype;
441     } else {
442         if (expression->ctype->size == 0)
443             compile_error("invalid operand to sizeof operator");
444         return expression->ctype;
445     }
446
447     return NULL;
448 }
449
450 static ast_t *parse_sizeof(void) {
451     data_type_t *type = parse_sizeof_operand();
452     if (type->type == TYPE_VOID || type->type == TYPE_FUNCTION)
453         return ast_new_integer(ast_data_table[AST_DATA_LONG], 1);
454     return ast_new_integer(ast_data_table[AST_DATA_LONG], type->size);
455 }
456
457 static int parse_alignment(data_type_t *type) {
458     int size = type->type == TYPE_ARRAY ? type->pointer->size : type->size;
459     return MIN(size, ARCH_ALIGNMENT);
460 }
461
462 static ast_t *parse_alignof(void) {
463     parse_expect('(');
464     data_type_t *type = parse_function_parameter(NULL, true);
465     parse_expect(')');
466     return ast_new_integer(ast_data_table[AST_DATA_LONG], parse_alignment(type));
467 }
468
469 static ast_t *parse_structure_field(ast_t *structure) {
470     if (structure->ctype->type != TYPE_STRUCTURE)
471         compile_error("expected structure type, `%s' isn't structure type", ast_string(structure));
472     lexer_token_t *name = lexer_next();
473     if (name->type != LEXER_TOKEN_IDENTIFIER)
474         compile_error("expected field name, got `%s' instead", lexer_token_string(name));
475
476     data_type_t *field = table_find(structure->ctype->fields, name->string);
477     if (!field)
478         compile_error("structure has no such field `%s'", lexer_token_string(name));
479     return ast_structure_reference(field, structure, name->string);
480 }
481
482 static void parse_static_assert(void) {
483     parse_expect('(');
484     int eval = parse_expression_evaluate();
485     parse_expect(',');
486     lexer_token_t *token = lexer_next();
487     if (token->type != LEXER_TOKEN_STRING)
488         compile_error("expected string");
489     parse_expect(')');
490     parse_expect(';');
491     if (!eval)
492         compile_error("static assertion failed: %s", token->string);
493 }
494
495 static ast_t *parse_label_address(void) {
496     lexer_token_t *token = lexer_next();
497     if (token->type != LEXER_TOKEN_IDENTIFIER)
498         compile_error("expected identifier");
499     ast_t *address = ast_label_address(token->string);
500     list_push(ast_gotos, address);
501     return address;
502 }
503
504 static ast_t *parse_expression_postfix_tail(ast_t *ast) {
505     if (!ast)
506         return NULL;
507     for (;;) {
508         if (parse_next('(')) {
509             data_type_t *type = ast->ctype;
510             if (type->type == TYPE_POINTER && type->pointer->type == TYPE_FUNCTION)
511                 return parse_function_pointer_call(ast);
512             if (ast->type != AST_TYPE_DESIGNATOR)
513                 compile_error("expected function name");
514             ast = parse_function_call(ast->function.name, ast->function.call.functionpointer);
515             continue;
516         }
517         if (ast->type == AST_TYPE_DESIGNATOR && !ast->function.call.functionpointer)
518             compile_error("undefined variable: %s", ast->function.name);
519
520         if (parse_next('[')) {
521             ast = parse_expression_subscript(ast);
522             continue;
523         }
524
525         if (parse_next('.')) {
526             ast = parse_structure_field(ast);
527             continue;
528         }
529
530         if (parse_next(LEXER_TOKEN_ARROW)) {
531             if (ast->ctype->type != TYPE_POINTER)
532                 compile_error("expected pointer type");
533             ast = ast_new_unary(AST_TYPE_DEREFERENCE, ast->ctype->pointer, ast);
534             ast = parse_structure_field(ast);
535             continue;
536         }
537
538         lexer_token_t *peek = lexer_peek();
539         if (parse_next(LEXER_TOKEN_INCREMENT) || parse_next(LEXER_TOKEN_DECREMENT)) {
540             parse_semantic_lvalue(ast);
541             int operation = lexer_ispunct(peek, LEXER_TOKEN_INCREMENT)
542                 ?   AST_TYPE_POST_INCREMENT
543                 :   AST_TYPE_POST_DECREMENT;
544
545             return ast_new_unary(operation, ast->ctype, ast);
546         }
547
548         return ast;
549     }
550
551     return NULL;
552 }
553
554 static ast_t *parse_expression_postfix(void) {
555     return parse_expression_postfix_tail(parse_expression_primary());
556 }
557
558 static ast_t *parse_expression_unary_address(void) {
559     ast_t *operand = parse_expression_cast();
560     if (operand->type == AST_TYPE_DESIGNATOR)
561         return ast_designator_convert(operand);
562     parse_semantic_lvalue(operand);
563     return ast_new_unary(AST_TYPE_ADDRESS, ast_pointer(operand->ctype), operand);
564 }
565
566 static ast_t *parse_expression_unary_deref(void) {
567     ast_t *operand = parse_expression_cast();
568     operand = ast_designator_convert(operand);
569     data_type_t *type = ast_array_convert(operand->ctype);
570     if (type->type != TYPE_POINTER)
571         compile_error("invalid type argument of unary ‘*’ (have ‘%s’)", ast_type_string(type));
572     if (type->pointer->type == TYPE_FUNCTION)
573         return operand;
574
575     return ast_new_unary(AST_TYPE_DEREFERENCE, operand->ctype->pointer, operand);
576 }
577
578 static ast_t *parse_expression_unary_plus(void) {
579     return parse_expression_cast();
580 }
581
582 static ast_t *parse_expression_unary_minus(void) {
583     ast_t *expression = parse_expression_cast();
584     // todo: semantic
585     return ast_new_unary(AST_TYPE_NEGATE, expression->ctype, expression);
586 }
587
588 static ast_t *parse_expression_unary_bitcomp(void) {
589     ast_t *expression = parse_expression_cast();
590     expression = ast_designator_convert(expression);
591     if (!ast_type_isinteger(expression->ctype))
592         compile_error("invalid argument type ‘%s‘ to bit-complement", ast_type_string(expression->ctype));
593
594     return ast_new_unary('~', expression->ctype, expression);
595 }
596
597 static ast_t *parse_expression_unary_not(void) {
598     ast_t *operand = parse_expression_cast();
599     operand = ast_designator_convert(operand);
600     return ast_new_unary('!', ast_data_table[AST_DATA_INT], operand);
601 }
602
603 static ast_t *parse_expression_unary(void) {
604     lexer_token_t *token = lexer_peek();
605     if (parse_identifer_check(token, "sizeof")) {
606         lexer_next();
607         return parse_sizeof();
608     }
609
610
611     if (parse_identifer_check(token, "__alignof__"))
612         goto alignof;
613
614     if (parse_identifer_check(token, "_Alignof")) {
615         if (!opt_std_test(STANDARD_C11) && !opt_std_test(STANDARD_LICEC))
616             compile_error("_Alignof not supported in this version of the standard, try -std=c11 or -std=licec");
617
618         alignof:
619         lexer_next();
620         return parse_alignof();
621     }
622
623     if (parse_next(LEXER_TOKEN_INCREMENT) || parse_next(LEXER_TOKEN_DECREMENT)) {
624         ast_t *operand = parse_expression_unary();
625         operand = ast_designator_convert(operand);
626         parse_semantic_lvalue(operand);
627         int operation = lexer_ispunct(token, LEXER_TOKEN_INCREMENT)
628                             ? AST_TYPE_PRE_INCREMENT
629                             : AST_TYPE_PRE_DECREMENT;
630
631         return ast_new_unary(operation, operand->ctype, operand);
632     }
633
634     /* &&label for computed goto */
635     if (parse_next(LEXER_TOKEN_AND))
636         return parse_label_address();
637
638     /* a more managable method for unary parsers */
639     static ast_t *(*const parsers['~'-'!'+1])(void) = {
640         [0]       = &parse_expression_unary_not,
641         ['&'-'!'] = &parse_expression_unary_address,
642         ['*'-'!'] = &parse_expression_unary_deref,
643         ['+'-'!'] = &parse_expression_unary_plus,
644         ['-'-'!'] = &parse_expression_unary_minus,
645         ['~'-'!'] = &parse_expression_unary_bitcomp
646     };
647
648     for (const char *test = "!&*+-~"; *test; test++)
649         if (parse_next(*test))
650             return parsers[*test-'!']();
651
652     return parse_expression_postfix();
653 }
654
655 ast_t *parse_expression_compound_literal(data_type_t *type) {
656     char   *name = ast_label();
657     list_t *init = init_entry(type);
658     ast_t  *ast  = ast_variable_local(type, name);
659     ast->variable.init = init;
660     return ast;
661 }
662
663 static data_type_t *parse_expression_cast_type(void) {
664     data_type_t *basetype = parse_declaration_specification(NULL);
665     return parse_declarator(NULL, basetype, NULL, CDECL_CAST);
666 }
667
668 static ast_t *parse_expression_cast(void) {
669     lexer_token_t *token = lexer_next();
670     if (lexer_ispunct(token, '(') && parse_type_check(lexer_peek())) {
671         data_type_t *type = parse_expression_cast_type();
672         parse_expect(')');
673         if (lexer_ispunct(lexer_peek(), '{')) {
674             ast_t *ast = parse_expression_compound_literal(type);
675             return parse_expression_postfix_tail(ast);
676         }
677         return ast_new_unary(AST_TYPE_EXPRESSION_CAST, type, parse_expression_cast());
678     }
679     lexer_unget(token);
680     return parse_expression_unary();
681 }
682
683 static ast_t *parse_expression_multiplicative(void) {
684     ast_t *ast = ast_designator_convert(parse_expression_cast());
685     for (;;) {
686              if (parse_next('*')) ast = conv_usual('*', ast, ast_designator_convert(parse_expression_cast()));
687         else if (parse_next('/')) ast = conv_usual('/', ast, ast_designator_convert(parse_expression_cast()));
688         else if (parse_next('%')) ast = conv_usual('%', ast, ast_designator_convert(parse_expression_cast()));
689         else break;
690     }
691     return ast;
692 }
693
694 static ast_t *parse_expression_additive(void) {
695     ast_t *ast = parse_expression_multiplicative();
696     for (;;) {
697              if (parse_next('+')) ast = conv_usual('+', ast, parse_expression_multiplicative());
698         else if (parse_next('-')) ast = conv_usual('-', ast, parse_expression_multiplicative());
699         else break;
700     }
701     return ast;
702 }
703
704 static ast_t *parse_expression_shift(void) {
705     ast_t *ast = parse_expression_additive();
706     for (;;) {
707         lexer_token_t *token = lexer_next();
708         int operation;
709         if (lexer_ispunct(token, LEXER_TOKEN_LSHIFT))
710             operation = AST_TYPE_LSHIFT;
711         else if (lexer_ispunct(token, LEXER_TOKEN_RSHIFT))
712             operation = ast->ctype->sign
713                             ? AST_TYPE_RSHIFT
714                             : AST_TYPE_LRSHIFT;
715         else {
716             lexer_unget(token);
717             break;
718         }
719         ast_t *right = parse_expression_additive();
720         // todo ensure integer
721         data_type_t *result = conv_senority(ast->ctype, right->ctype);
722         ast = ast_new_binary(result, operation, ast, right);
723     }
724     return ast;
725 }
726
727 static ast_t *parse_expression_relational(void) {
728     ast_t *ast = parse_expression_shift();
729     for (;;) {
730              if (parse_next('<'))                ast = conv_usual('<',             ast, parse_expression_shift());
731         else if (parse_next('>'))                ast = conv_usual('>',             ast, parse_expression_shift());
732         else if (parse_next(LEXER_TOKEN_LEQUAL)) ast = conv_usual(AST_TYPE_LEQUAL, ast, parse_expression_shift());
733         else if (parse_next(LEXER_TOKEN_GEQUAL)) ast = conv_usual(AST_TYPE_GEQUAL, ast, parse_expression_shift());
734         else break;
735     }
736     return ast;
737 }
738
739 static ast_t *parse_expression_equality(void) {
740     ast_t *ast = parse_expression_relational();
741     if (parse_next(LEXER_TOKEN_EQUAL))
742         return conv_usual(AST_TYPE_EQUAL, ast, parse_expression_equality());
743     if (parse_next(LEXER_TOKEN_NEQUAL))
744         return conv_usual(AST_TYPE_NEQUAL, ast, parse_expression_equality());
745     return ast;
746 }
747
748 static ast_t *parse_expression_bitand(void) {
749     ast_t *ast = parse_expression_equality();
750     while (parse_next('&'))
751         ast = conv_usual('&', ast, parse_expression_equality());
752     return ast;
753 }
754
755 static ast_t *parse_expression_bitxor(void) {
756     ast_t *ast = parse_expression_bitand();
757     while (parse_next('^'))
758         ast = conv_usual('^', ast, parse_expression_bitand());
759     return ast;
760 }
761
762 static ast_t *parse_expression_bitor(void) {
763     ast_t *ast = parse_expression_bitxor();
764     while (parse_next('|'))
765         ast = conv_usual('|', ast, parse_expression_bitxor());
766     return ast;
767 }
768
769 static ast_t *parse_expression_logand(void) {
770     ast_t *ast = parse_expression_bitor();
771     while (parse_next(LEXER_TOKEN_AND))
772         ast = ast_new_binary(ast_data_table[AST_DATA_INT], AST_TYPE_AND, ast, parse_expression_bitor());
773     return ast;
774 }
775
776 static ast_t *parse_expression_logor(void) {
777     ast_t *ast = parse_expression_logand();
778     while (parse_next(LEXER_TOKEN_OR))
779         ast = ast_new_binary(ast_data_table[AST_DATA_INT], AST_TYPE_OR, ast, parse_expression_logand());
780     return ast;
781 }
782
783 ast_t *parse_expression_assignment(void) {
784     ast_t         *ast   = parse_expression_logor();
785     lexer_token_t *token = lexer_next();
786
787     if (!token)
788         return ast;
789
790     if (lexer_ispunct(token, '?')) {
791         ast_t *then = parse_expression_comma();
792         parse_expect(':');
793         ast_t *last = parse_expression_conditional();
794         ast_t *operand = (opt_extension_test(EXTENSION_OMITOPCOND)) ? last : then;
795         return ast_ternary(operand->ctype, ast, then, last);
796     }
797
798     int compound   = parse_operation_compound_operator(token);
799     int reclassify = parse_operation_reclassify(compound);
800     if (lexer_ispunct(token, '=') || compound) {
801         ast_t *value = parse_expression_assignment();
802         if (lexer_ispunct(token, '=') || compound)
803             parse_semantic_lvalue(ast);
804
805         ast_t *right = compound ? conv_usual(reclassify, ast, value) : value;
806         if (conv_capable(right->ctype) && ast->ctype->type != right->ctype->type)
807             right = ast_type_convert(ast->ctype, right);
808         return ast_new_binary(ast->ctype, '=', ast, right);
809     }
810
811     lexer_unget(token);
812     return ast;
813 }
814
815 static ast_t *parse_expression_comma(void) {
816     ast_t *ast = parse_expression_assignment();
817     while (parse_next(',')) {
818         ast_t *expression = parse_expression_assignment();
819         ast = ast_new_binary(expression->ctype, ',', ast, expression);
820     }
821     return ast;
822 }
823
824 static ast_t *parse_expression(void) {
825     ast_t *ast = parse_expression_comma();
826     if (!ast)
827         compile_error("expression expected");
828     return ast;
829 }
830
831 static ast_t *parse_expression_optional(void) {
832     return parse_expression_comma();
833 }
834
835 static ast_t *parse_expression_condition(void) {
836     ast_t *cond = parse_expression();
837     if (ast_type_isfloating(cond->ctype))
838         return ast_type_convert(ast_data_table[TYPE_BOOL], cond);
839     return cond;
840 }
841
842 static ast_t *parse_expression_conditional(void) {
843     ast_t *ast = parse_expression_logor();
844     if (!parse_next('?'))
845         return ast;
846     ast_t *then = parse_expression_comma();
847     parse_expect(':');
848     ast_t *last = parse_expression_conditional();
849     return ast_ternary(last->ctype, ast, then, last);
850 }
851
852 int parse_expression_evaluate(void) {
853     return parse_evaluate(parse_expression_conditional());
854 }
855
856 static bool parse_type_check(lexer_token_t *token) {
857     if (token->type != LEXER_TOKEN_IDENTIFIER)
858         return false;
859
860     static const char *keywords[] = {
861         "char",     "short",  "int",      "long",     "float",    "double",
862         "struct",   "union",  "signed",   "unsigned", "enum",     "void",
863         "typedef",  "extern", "static",   "auto",     "register", "const",
864         "volatile", "inline", "restrict", "typeof",   "_Bool",
865
866         /*
867          * Ironically there is also another way to specific some keywords
868          * in C due to compilers being sneaky. Thus some code may use
869          * things like, __static__, or __typeof__, which are compilers
870          * reserved implementations of those keywords before the standard
871          * was ratified.
872          */
873         "__static__",
874         "__typeof__",
875     };
876
877     for (size_t i = 0; i < sizeof(keywords) / sizeof(keywords[0]); i++)
878         if (!strcmp(keywords[i], token->string))
879             return true;
880
881     if (table_find(parse_typedefs, token->string))
882         return true;
883
884     return false;
885 }
886
887 /* struct / union */
888 static char *parse_memory_tag(void) {
889     lexer_token_t *token = lexer_next();
890     if (token->type == LEXER_TOKEN_IDENTIFIER)
891         return token->string;
892     lexer_unget(token);
893     return NULL;
894 }
895
896 static int parse_memory_fields_padding(int offset, data_type_t *type) {
897     int size = type->type == TYPE_ARRAY ? type->pointer->size : type->size;
898     size = MIN(size, ARCH_ALIGNMENT);
899     return (offset % size == 0) ? 0 : size - offset % size;
900 }
901
902 static void parse_memory_fields_flexiblize(list_t *fields) {
903     list_iterator_t *it = list_iterator(fields);
904     while (!list_iterator_end(it)) {
905         pair_t      *pair = list_iterator_next(it);
906         char        *name = pair->first;
907         data_type_t *type = pair->second;
908
909         if (type->type != TYPE_ARRAY)
910             continue;
911
912         if (!opt_std_test(STANDARD_GNUC) && !opt_std_test(STANDARD_LICEC)) {
913             if (type->length == 0)
914                 type->length = -1;
915         }
916
917         if (type->length == -1) {
918             if (!list_iterator_end(it))
919                 compile_error("flexible field %s can only appear as the last field in a structure", name);
920             if (list_length(fields) == 1)
921                 compile_error("flexible field %s as only field in structure is illegal", name);
922             type->size = 0;
923         }
924     }
925 }
926
927 static void parse_memory_fields_squash(table_t *table, data_type_t *unnamed, int offset) {
928     for (list_iterator_t *it = list_iterator(table_keys(unnamed->fields)); !list_iterator_end(it); ) {
929         char         *name = list_iterator_next(it);
930         data_type_t  *type = ast_type_copy(table_find(unnamed->fields, name));
931         type->offset += offset;
932         table_insert(table, name, type);
933     }
934 }
935
936 static int parse_bitfield_maybe(char *name, data_type_t *through) {
937     if (!parse_next(':'))
938         return -1;
939     if (!ast_type_isinteger(through))
940         compile_error("invalid type for bitfield size %s", ast_type_string(through));
941     int evaluate = parse_expression_evaluate();
942     if (evaluate < 0 || through->size * 8 < evaluate)
943         compile_error("invalid bitfield size %s: %d", ast_type_string(through), evaluate);
944     if (evaluate == 0 && name)
945         compile_error("zero sized bitfield cannot be named");
946     return evaluate;
947 }
948
949 static list_t *parse_memory_fields_intermediate(void) {
950     list_t *list = list_create();
951     for (;;) {
952
953         lexer_token_t *next = lexer_next();
954         if (parse_identifer_check(next, "_Static_assert")) {
955             if (!opt_std_test(STANDARD_C11) && !opt_std_test(STANDARD_LICEC))
956                 compile_error("_Static_assert not supported in this version of the standard, try -std=c11 or -std=licec");
957
958             parse_static_assert();
959             continue;
960         }
961
962         lexer_unget(next);
963
964         if (!parse_type_check(lexer_peek()))
965             break;
966
967         data_type_t *basetype = parse_declaration_specification(NULL);
968
969         if (basetype->type == TYPE_STRUCTURE && parse_next(';')) {
970             list_push(list, pair_create(NULL, basetype));
971             continue;
972         }
973
974         for (;;) {
975             char        *name      = NULL;
976             data_type_t *fieldtype = parse_declarator(&name, basetype, NULL, CDECL_TYPEONLY);
977             parse_semantic_notvoid(fieldtype);
978
979             /* copy though for bitfield */
980             fieldtype                = ast_type_copy(fieldtype);
981             fieldtype->bitfield.size = parse_bitfield_maybe(name, fieldtype);
982
983             list_push(list, pair_create(name, fieldtype));
984
985             if (parse_next(','))
986                 continue;
987             if (lexer_ispunct(lexer_peek(), '}'))
988                 compile_warn("no semicolon at end of struct or union");
989             else
990                 parse_expect(';');
991             break;
992         }
993     }
994     parse_expect('}');
995     return list;
996 }
997
998 static void parse_bitfield_update(int *offset, int *bitfield) {
999     *offset  += (*bitfield + 8) / 8;
1000     *bitfield = -1;
1001 }
1002
1003 static table_t *parse_struct_offset(list_t *fields, int *size) {
1004     int              offset   = 0;
1005     int              bitfield = -1;
1006     list_iterator_t *it       = list_iterator(fields);
1007     table_t         *table    = table_create(NULL);
1008
1009     while (!list_iterator_end(it)) {
1010         pair_t      *pair = list_iterator_next(it);
1011         char        *name = pair->first;
1012         data_type_t *type = pair->second;
1013
1014         if (!name && type->type == TYPE_STRUCTURE) {
1015             parse_bitfield_update(&offset, &bitfield);
1016             parse_memory_fields_squash(table, type, offset);
1017             offset += type->size;
1018             continue;
1019         }
1020         if (type->bitfield.size == 0) {
1021             parse_bitfield_update(&offset, &bitfield);
1022             offset += parse_memory_fields_padding(offset, type);
1023             bitfield = 0;
1024             continue;
1025         }
1026         if (type->bitfield.size >= 0) {
1027             /* bitfield space */
1028             int space = type->size * 8 - bitfield;
1029             if (0 <= bitfield && type->bitfield.size <= space) {
1030                 type->bitfield.offset = bitfield;
1031                 type->offset          = offset;
1032             } else {
1033                 parse_bitfield_update(&offset, &bitfield);
1034                 offset               += parse_memory_fields_padding(offset, type);
1035                 type->offset          = offset;
1036                 type->bitfield.offset = 0;
1037             }
1038             bitfield = type->bitfield.size;
1039         } else {
1040             parse_bitfield_update(&offset, &bitfield);
1041             offset += parse_memory_fields_padding(offset, type);
1042             type->offset = offset;
1043             offset += type->size;
1044         }
1045         if (name)
1046             table_insert(table, name, type); /* no copy needed */
1047     }
1048     parse_bitfield_update(&offset, &bitfield); /* stage it */
1049     *size = offset;
1050     return table;
1051 }
1052
1053 static table_t *parse_union_offset(list_t *fields, int *size) {
1054     int              maxsize = 0;
1055     list_iterator_t *it      = list_iterator(fields);
1056     table_t         *table   = table_create(NULL);
1057
1058     while (!list_iterator_end(it)) {
1059         pair_t      *pair = list_iterator_next(it);
1060         char        *name = pair->first;
1061         data_type_t *type = pair->second;
1062
1063         maxsize = MAX(maxsize, type->size);
1064         if (!name && type->type == TYPE_STRUCTURE) {
1065             parse_memory_fields_squash(table, type, 0);
1066             continue;
1067         }
1068         type->offset = 0;
1069         if (type->bitfield.size >= 0)
1070             type->bitfield.offset = 0;
1071         if (name)
1072             table_insert(table, name, type);
1073     }
1074     *size = maxsize;
1075     return table;
1076 }
1077
1078 static table_t *parse_memory_fields(int *size, bool isstruct) {
1079     if (!parse_next('{'))
1080         return NULL;
1081     list_t *fields = parse_memory_fields_intermediate();
1082
1083     /* make flexible if it can be made flexible */
1084     parse_memory_fields_flexiblize(fields);
1085
1086     return (isstruct)
1087                 ? parse_struct_offset(fields, size)
1088                 : parse_union_offset(fields, size);
1089 }
1090
1091 static data_type_t *parse_tag_definition(table_t *table, bool isstruct) {
1092     char        *tag = parse_memory_tag();
1093     data_type_t *r;
1094
1095     if (tag) {
1096         if (!(r = table_find(table, tag))) {
1097             r = ast_structure_new(NULL, 0, isstruct);
1098             table_insert(table, tag, r);
1099         }
1100     } else {
1101         r = ast_structure_new(NULL, 0, isstruct);
1102     }
1103
1104     int      size   = 0;
1105     table_t *fields = parse_memory_fields(&size, isstruct);
1106
1107     if (r && !fields)
1108         return r;
1109
1110     if (r && fields) {
1111         r->fields = fields;
1112         r->size   = size;
1113         return r;
1114     }
1115
1116     return NULL;
1117 }
1118
1119 /* enum */
1120 data_type_t *parse_enumeration(void) {
1121     lexer_token_t *token = lexer_next();
1122     if (token->type == LEXER_TOKEN_IDENTIFIER)
1123         token = lexer_next();
1124     if (!lexer_ispunct(token, '{')) {
1125         lexer_unget(token);
1126         return ast_data_table[AST_DATA_INT];
1127     }
1128     int accumulate = 0;
1129     for (;;) {
1130         token = lexer_next();
1131         if (lexer_ispunct(token, '}'))
1132             break;
1133
1134         if (token->type != LEXER_TOKEN_IDENTIFIER)
1135             compile_error("expected identifier before ‘%s’ token", lexer_token_string(token));
1136
1137         char *name = token->string;
1138         token = lexer_next();
1139         if (lexer_ispunct(token, '='))
1140             accumulate = parse_expression_evaluate();
1141         else
1142             lexer_unget(token);
1143
1144         ast_t *constval = ast_new_integer(ast_data_table[AST_DATA_INT], accumulate++);
1145         table_insert(ast_localenv ? ast_localenv : ast_globalenv, name, constval);
1146         token = lexer_next();
1147         if (lexer_ispunct(token, ','))
1148             continue;
1149         if (lexer_ispunct(token, '}'))
1150             break;
1151
1152         compile_ice("parse_enumeration");
1153     }
1154     return ast_data_table[AST_DATA_INT];
1155 }
1156
1157 data_type_t *parse_typeof(void) {
1158     parse_expect('(');
1159     data_type_t *type = parse_type_check(lexer_peek())
1160                             ? parse_expression_cast_type()
1161                             : parse_expression_comma()->ctype;
1162     parse_expect(')');
1163     return type;
1164 }
1165
1166 data_type_t *parse_structure(void) {
1167     return parse_tag_definition(ast_structures, true);
1168 }
1169
1170 data_type_t *parse_union(void) {
1171     return parse_tag_definition(ast_unions, false);
1172 }
1173
1174 data_type_t *parse_typedef_find(const char *key) {
1175     return table_find(parse_typedefs, key);
1176 }
1177
1178 /* declarator */
1179 static data_type_t *parse_declaration_specification(storage_t *rstorage) {
1180     lexer_token_t *token   = lexer_peek();
1181     if (!token || token->type != LEXER_TOKEN_IDENTIFIER)
1182         compile_ice("declaration specification");
1183
1184     data_type_t *decl_spec(storage_t *);
1185     return decl_spec(rstorage);
1186 }
1187
1188 static data_type_t *parse_function_parameter(char **name, bool next) {
1189     data_type_t *basetype;
1190     storage_t    storage;
1191
1192     basetype = parse_declaration_specification(&storage);
1193     return parse_declarator(name, basetype, NULL, next ? CDECL_TYPEONLY : CDECL_PARAMETER);
1194 }
1195
1196 static ast_t *parse_statement_if(void) {
1197     lexer_token_t *token;
1198     ast_t  *cond;
1199     ast_t *then;
1200     ast_t *last;
1201
1202     parse_expect('(');
1203     cond = parse_expression_condition();
1204     parse_expect(')');
1205
1206
1207     then  = parse_statement();
1208     token = lexer_next();
1209
1210     if (!token || token->type != LEXER_TOKEN_IDENTIFIER || strcmp(token->string, "else")) {
1211         lexer_unget(token);
1212         return ast_if(cond, then, NULL);
1213     }
1214
1215     last = parse_statement();
1216     return ast_if(cond, then, last);
1217 }
1218
1219 static ast_t *parse_statement_declaration_semicolon(void) {
1220     lexer_token_t *token = lexer_next();
1221     if (lexer_ispunct(token, ';'))
1222         return NULL;
1223     lexer_unget(token);
1224     list_t *list = list_create();
1225     parse_statement_declaration(list);
1226     return list_shift(list);
1227 }
1228
1229 static ast_t *parse_statement_for(void) {
1230     parse_expect('(');
1231     ast_localenv = table_create(ast_localenv);
1232     ast_t *init = parse_statement_declaration_semicolon();
1233     ast_t *cond = parse_expression_optional();
1234     if (cond && ast_type_isfloating(cond->ctype))
1235         cond = ast_type_convert(ast_data_table[AST_DATA_BOOL], cond);
1236     parse_expect(';');
1237     ast_t *step = parse_expression_optional();
1238     parse_expect(')');
1239     ast_t *body = parse_statement();
1240     ast_localenv = table_parent(ast_localenv);
1241     return ast_for(init, cond, step, body);
1242 }
1243
1244 static ast_t *parse_statement_while(void) {
1245     parse_expect('(');
1246     ast_t *cond = parse_expression_condition();
1247     parse_expect(')');
1248     ast_t *body = parse_statement();
1249     return ast_while(cond, body);
1250 }
1251
1252 static ast_t *parse_statement_do(void) {
1253     ast_t         *body  = parse_statement();
1254     lexer_token_t *token = lexer_next();
1255
1256     if (!parse_identifer_check(token, "while"))
1257         compile_error("expected ‘while’ before ‘%s’ token", lexer_token_string(token));
1258
1259     parse_expect('(');
1260     ast_t *cond = parse_expression_condition();
1261     parse_expect(')');
1262     parse_expect(';');
1263
1264     return ast_do(cond, body);
1265 }
1266
1267 static ast_t *parse_statement_break(void) {
1268     parse_expect(';');
1269     return ast_make(AST_TYPE_STATEMENT_BREAK);
1270 }
1271
1272 static ast_t *parse_statement_continue(void) {
1273     parse_expect(';');
1274     return ast_make(AST_TYPE_STATEMENT_CONTINUE);
1275 }
1276
1277 static ast_t *parse_statement_switch(void) {
1278     parse_expect('(');
1279     ast_t *expression = parse_expression();
1280
1281     if (!ast_type_isinteger(expression->ctype)) {
1282         compile_error(
1283             "switch statement requires expression of integer type (‘%s‘ invalid)",
1284             ast_type_string(expression->ctype)
1285         );
1286     }
1287
1288     parse_expect(')');
1289     ast_t *body = parse_statement();
1290     return ast_switch(expression, body);
1291 }
1292
1293 static ast_t *parse_statement_case(void) {
1294     int begin = parse_expression_evaluate();
1295     int end;
1296     lexer_token_t *token = lexer_next();
1297     if (parse_identifer_check(token, "..."))
1298         end = parse_expression_evaluate();
1299     else {
1300         end = begin;
1301         lexer_unget(token);
1302     }
1303     parse_expect(':');
1304     if (begin > end)
1305         compile_warn("empty case range specified");
1306     return ast_case(begin, end);
1307 }
1308
1309 static ast_t *parse_statement_default(void) {
1310     parse_expect(':');
1311     return ast_make(AST_TYPE_STATEMENT_DEFAULT);
1312 }
1313
1314 static ast_t *parse_statement_return(void) {
1315     ast_t *val = parse_expression_optional();
1316     parse_expect(';');
1317     if (val)
1318         return ast_return(ast_type_convert(ast_data_table[AST_DATA_FUNCTION]->returntype, val));
1319     return ast_return(NULL);
1320 }
1321
1322 static ast_t *parse_statement_goto(void) {
1323     /* deal with computed goto */
1324     if (parse_next('*')) {
1325         ast_t *expression = parse_expression_cast();
1326         if (expression->ctype->type != TYPE_POINTER)
1327             compile_error("expected pointer type for computed goto");
1328         return ast_goto_computed(expression);
1329     }
1330
1331     /* otherwise the traditional route */
1332
1333     lexer_token_t *token = lexer_next();
1334     if (!token || token->type != LEXER_TOKEN_IDENTIFIER)
1335         compile_error("expected label in goto statement");
1336     parse_expect(';');
1337
1338     ast_t *node = ast_goto(token->string);
1339     list_push(ast_gotos, node);
1340
1341     return node;
1342 }
1343
1344 static void parse_label_backfill(void) {
1345     for (list_iterator_t *it = list_iterator(ast_gotos); !list_iterator_end(it); ) {
1346         ast_t *source      = list_iterator_next(it);
1347         char  *label       = source->gotostmt.label;
1348         ast_t *destination = table_find(ast_labels, label);
1349
1350         if (!destination)
1351             compile_error("undefined label ‘%s‘", label);
1352         if (destination->gotostmt.where)
1353             source->gotostmt.where = destination->gotostmt.where;
1354         else
1355             source->gotostmt.where = destination->gotostmt.where = ast_label();
1356     }
1357 }
1358
1359 static ast_t *parse_label(lexer_token_t *token) {
1360     parse_expect(':');
1361     char  *label = token->string;
1362     ast_t *node  = ast_new_label(label);
1363
1364     if (table_find(ast_labels, label))
1365         compile_error("duplicate label ‘%s‘", label);
1366     table_insert(ast_labels, label, node);
1367
1368     return node;
1369 }
1370
1371 static ast_t *parse_statement(void) {
1372     lexer_token_t *token = lexer_next();
1373     ast_t         *ast;
1374
1375     if (lexer_ispunct        (token, '{'))        return parse_statement_compound();
1376     if (parse_identifer_check(token, "if"))       return parse_statement_if();
1377     if (parse_identifer_check(token, "for"))      return parse_statement_for();
1378     if (parse_identifer_check(token, "while"))    return parse_statement_while();
1379     if (parse_identifer_check(token, "do"))       return parse_statement_do();
1380     if (parse_identifer_check(token, "return"))   return parse_statement_return();
1381     if (parse_identifer_check(token, "switch"))   return parse_statement_switch();
1382     if (parse_identifer_check(token, "case"))     return parse_statement_case();
1383     if (parse_identifer_check(token, "default"))  return parse_statement_default();
1384     if (parse_identifer_check(token, "break"))    return parse_statement_break();
1385     if (parse_identifer_check(token, "continue")) return parse_statement_continue();
1386     if (parse_identifer_check(token, "goto"))     return parse_statement_goto();
1387
1388     if (token->type == LEXER_TOKEN_IDENTIFIER && lexer_ispunct(lexer_peek(), ':'))
1389         return parse_label(token);
1390
1391     lexer_unget(token);
1392
1393     ast = parse_expression_optional();
1394     parse_expect(';');
1395
1396     return ast;
1397 }
1398
1399 static void parse_statement_declaration(list_t *list){
1400     lexer_token_t *token = lexer_peek();
1401     if (!token)
1402         compile_error("statement declaration with unexpected ending");
1403     if (parse_type_check(token)) {
1404         parse_declaration(list, ast_variable_local);
1405     } else {
1406         lexer_token_t *next = lexer_next();
1407         if (parse_identifer_check(next, "_Static_assert"))
1408             return parse_static_assert();
1409         else
1410             lexer_unget(next);
1411         ast_t *statement = parse_statement();
1412         if (statement)
1413             list_push(list, statement);
1414     }
1415 }
1416
1417 static ast_t *parse_statement_compound(void) {
1418     ast_localenv = table_create(ast_localenv);
1419     list_t *statements = list_create();
1420     for (;;) {
1421         lexer_token_t *token = lexer_next();
1422         if (lexer_ispunct(token, '}'))
1423             break;
1424
1425         lexer_unget(token);
1426         parse_statement_declaration(statements);
1427     }
1428     ast_localenv = table_parent(ast_localenv);
1429     return ast_compound(statements);
1430 }
1431
1432 static data_type_t *parse_function_parameters(list_t *paramvars, data_type_t *returntype) {
1433     bool           typeonly   = !paramvars;
1434     list_t        *paramtypes = list_create();
1435     lexer_token_t *token      = lexer_next();
1436     lexer_token_t *next       = lexer_next();
1437
1438     if (parse_identifer_check(token, "void") && lexer_ispunct(next, ')'))
1439         return ast_prototype(returntype, paramtypes, false);
1440     lexer_unget(next);
1441     if (lexer_ispunct(token, ')'))
1442         return ast_prototype(returntype, paramtypes, true);
1443     lexer_unget(token);
1444
1445     for (;;) {
1446         token = lexer_next();
1447         if (parse_identifer_check(token, "...")) {
1448             if (list_length(paramtypes) == 0)
1449                 compile_ice("parse_function_parameters");
1450             parse_expect(')');
1451             return ast_prototype(returntype, paramtypes, true);
1452         } else {
1453             lexer_unget(token);
1454         }
1455
1456         char        *name;
1457         data_type_t *ptype = parse_function_parameter(&name, typeonly);
1458         parse_semantic_notvoid(ptype);
1459
1460         if (ptype->type == TYPE_ARRAY)
1461             ptype = ast_pointer(ptype->pointer);
1462         list_push(paramtypes, ptype);
1463
1464         if (!typeonly)
1465             list_push(paramvars, ast_variable_local(ptype, name));
1466
1467         lexer_token_t *token = lexer_next();
1468         if (lexer_ispunct(token, ')'))
1469             return ast_prototype(returntype, paramtypes, false);
1470
1471         if (!lexer_ispunct(token, ','))
1472             compile_ice("parse_function_parameters");
1473     }
1474 }
1475
1476 static ast_t *parse_function_definition(data_type_t *functype, char *name, list_t *parameters) {
1477     ast_localenv                      = table_create(ast_localenv);
1478     ast_locals                        = list_create();
1479     ast_data_table[AST_DATA_FUNCTION] = functype;
1480
1481     table_insert(ast_localenv, "__func__", ast_new_string(name));
1482
1483     ast_t *body = parse_statement_compound();
1484     ast_t *r    = ast_function(functype, name, parameters, body, ast_locals);
1485
1486     table_insert(ast_globalenv, name, r);
1487
1488     ast_data_table[AST_DATA_FUNCTION] = NULL;
1489     ast_localenv                      = NULL;
1490     ast_locals                        = NULL;
1491
1492     return r;
1493 }
1494
1495 static bool parse_function_definition_check(void) {
1496     list_t *buffer = list_create();
1497     int     nests  = 0;
1498     bool    paren  = false;
1499     bool    ready  = true;
1500
1501     for (;;) {
1502
1503         lexer_token_t *token = lexer_next();
1504         list_push(buffer, token);
1505
1506         if (!token)
1507             compile_error("function definition with unexpected ending");
1508
1509         if (nests == 0 && paren && lexer_ispunct(token, '{'))
1510             break;
1511
1512         if (nests == 0 && (lexer_ispunct(token, ';')
1513                          ||lexer_ispunct(token, ',')
1514                          ||lexer_ispunct(token, '=')))
1515         {
1516             ready = false;
1517             break;
1518         }
1519
1520         if (lexer_ispunct(token, '('))
1521             nests++;
1522
1523         if (lexer_ispunct(token, ')')) {
1524             if (nests == 0)
1525                 compile_error("unmatched parenthesis");
1526             paren = true;
1527             nests--;
1528         }
1529     }
1530
1531     while (list_length(buffer) > 0)
1532         lexer_unget(list_pop(buffer));
1533
1534     return ready;
1535 }
1536
1537 static ast_t *parse_function_definition_intermediate(void) {
1538     char        *name;
1539     storage_t    storage;
1540     list_t      *parameters = list_create();
1541     data_type_t *basetype   = ast_data_table[AST_DATA_INT];
1542
1543     if (parse_type_check(lexer_peek()))
1544         basetype = parse_declaration_specification(&storage);
1545     else
1546         compile_warn("return type defaults to ’int’");
1547
1548     ast_localenv = table_create(ast_globalenv);
1549     ast_labels   = table_create(NULL);
1550     ast_gotos    = list_create();
1551
1552     data_type_t *functype = parse_declarator(&name, basetype, parameters, CDECL_BODY);
1553     functype->isstatic = !!(storage == STORAGE_STATIC);
1554     ast_variable_global(functype, name);
1555     parse_expect('{');
1556     ast_t *value = parse_function_definition(functype, name, parameters);
1557
1558     parse_label_backfill();
1559
1560     ast_localenv = NULL;
1561     return value;
1562 }
1563
1564 static data_type_t *parse_declarator_direct_restage(data_type_t *basetype, list_t *parameters) {
1565     lexer_token_t *token = lexer_next();
1566     if (lexer_ispunct(token, '[')) {
1567         int length;
1568         token = lexer_next();
1569         if (lexer_ispunct(token, ']'))
1570             length = -1;
1571         else {
1572             lexer_unget(token);
1573             length = parse_expression_evaluate();
1574             parse_expect(']');
1575         }
1576
1577         data_type_t *type = parse_declarator_direct_restage(basetype, parameters);
1578         if (type->type == TYPE_FUNCTION)
1579             compile_error("array of functions");
1580         return ast_array(type, length);
1581     }
1582     if (lexer_ispunct(token, '(')) {
1583         if (basetype->type == TYPE_FUNCTION)
1584             compile_error("function returning function");
1585         if (basetype->type == TYPE_ARRAY)
1586             compile_error("function returning array");
1587         return parse_function_parameters(parameters, basetype);
1588     }
1589     lexer_unget(token);
1590     return basetype;
1591 }
1592
1593 static void parse_qualifiers_skip(void) {
1594     for (;;) {
1595         lexer_token_t *token = lexer_next();
1596         if (parse_identifer_check(token, "const")
1597          || parse_identifer_check(token, "volatile")
1598          || parse_identifer_check(token, "restrict")) {
1599             continue;
1600         }
1601         lexer_unget(token);
1602         return;
1603     }
1604 }
1605
1606 static data_type_t *parse_declarator_direct(char **rname, data_type_t *basetype, list_t *parameters, cdecl_t context) {
1607     lexer_token_t *token = lexer_next();
1608     lexer_token_t *next  = lexer_peek();
1609
1610     if (lexer_ispunct(token, '(') && !parse_type_check(next) && !lexer_ispunct(next, ')')) {
1611         data_type_t *stub = ast_type_stub();
1612         data_type_t *type = parse_declarator_direct(rname, stub, parameters, context);
1613         parse_expect(')');
1614         *stub = *parse_declarator_direct_restage(basetype, parameters);
1615         return type;
1616     }
1617
1618     if (lexer_ispunct(token, '*')) {
1619         parse_qualifiers_skip();
1620         data_type_t *stub = ast_type_stub();
1621         data_type_t *type = parse_declarator_direct(rname, stub, parameters, context);
1622         *stub = *ast_pointer(basetype);
1623         return type;
1624     }
1625
1626     if (token->type == LEXER_TOKEN_IDENTIFIER) {
1627         if (context == CDECL_CAST)
1628             compile_error("wasn't expecting identifier `%s'", lexer_token_string(token));
1629         *rname = token->string;
1630         return parse_declarator_direct_restage(basetype, parameters);
1631     }
1632
1633     if (context == CDECL_BODY || context == CDECL_PARAMETER)
1634         compile_error("expected identifier, `(` or `*` for declarator");
1635
1636     lexer_unget(token);
1637
1638     return parse_declarator_direct_restage(basetype, parameters);
1639 }
1640
1641 static void parse_array_fix(data_type_t *type) {
1642     if (type->type == TYPE_ARRAY) {
1643         parse_array_fix(type->pointer);
1644         type->size = type->length * type->pointer->size;
1645     } else if (type->type == TYPE_POINTER) {
1646         parse_array_fix(type->pointer);
1647     } else if (type->type == TYPE_FUNCTION) {
1648         parse_array_fix(type->returntype);
1649     }
1650 }
1651
1652 static data_type_t *parse_declarator(char **rname, data_type_t *basetype, list_t *parameters, cdecl_t context) {
1653     data_type_t *type = parse_declarator_direct(rname, basetype, parameters, context);
1654     parse_array_fix(type);
1655     return type;
1656 }
1657
1658 static void parse_declaration(list_t *list, ast_t *(*make)(data_type_t *, char *)) {
1659     storage_t      storage;
1660     data_type_t   *basetype = parse_declaration_specification(&storage);
1661     lexer_token_t *token    = lexer_next();
1662
1663     if (lexer_ispunct(token, ';'))
1664         return;
1665
1666     lexer_unget(token);
1667
1668     for (;;) {
1669         char        *name = NULL;
1670         data_type_t *type = parse_declarator(&name, ast_type_copy_incomplete(basetype), NULL, CDECL_BODY);
1671
1672         if (storage == STORAGE_STATIC)
1673             type->isstatic = true;
1674
1675         token = lexer_next();
1676         if (lexer_ispunct(token, '=')) {
1677             if (storage == STORAGE_TYPEDEF)
1678                 compile_error("invalid use of typedef");
1679             parse_semantic_notvoid(type);
1680             ast_t *var = make(type, name);
1681             list_push(list, ast_declaration(var, init_entry(var->ctype)));
1682             token = lexer_next();
1683         } else if (storage == STORAGE_TYPEDEF) {
1684             table_insert(parse_typedefs, name, type);
1685         } else if (type->type == TYPE_FUNCTION) {
1686             make(type, name);
1687         } else {
1688             ast_t *var = make(type, name);
1689             if (storage != STORAGE_EXTERN)
1690                 list_push(list, ast_declaration(var, NULL));
1691         }
1692         if (lexer_ispunct(token, ';'))
1693             return;
1694         if (!lexer_ispunct(token, ','))
1695             compile_ice("confused %X", token);
1696     }
1697 }
1698
1699 list_t *parse_run(void) {
1700     list_t *list = list_create();
1701     for (;;) {
1702         if (!lexer_peek())
1703             return list;
1704         if (parse_function_definition_check())
1705             list_push(list, parse_function_definition_intermediate());
1706         else
1707             parse_declaration(list, &ast_variable_global);
1708     }
1709     return NULL;
1710 }
1711
1712 void parse_init(void) {
1713     data_type_t *voidp = ast_pointer(ast_data_table[AST_DATA_VOID]);
1714     data_type_t *type  = ast_prototype(voidp, list_create(), true);
1715     data_type_t *addr  = ast_prototype(voidp, list_default(ast_data_table[AST_DATA_ULONG]), true);
1716
1717     table_insert(ast_globalenv, "__builtin_va_start",       ast_variable_global(type, "__builtin_va_start"));
1718     table_insert(ast_globalenv, "__builtin_va_arg",         ast_variable_global(type, "__builtin_va_arg"));
1719     table_insert(ast_globalenv, "__builtin_return_address", ast_variable_global(addr, "__buitlin_return_address"));
1720 }