]> git.xonotic.org Git - xonotic/gmqcc.git/blob - parser.c
Making logical 'and' and 'or' use NOT_ in -fcorrect-logic for both operands normally...
[xonotic/gmqcc.git] / parser.c
1 /*
2  * Copyright (C) 2012
3  *     Wolfgang Bumiller
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a copy of
6  * this software and associated documentation files (the "Software"), to deal in
7  * the Software without restriction, including without limitation the rights to
8  * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
9  * of the Software, and to permit persons to whom the Software is furnished to do
10  * so, subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be included in all
13  * copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21  * SOFTWARE.
22  */
23 #include <stdio.h>
24 #include <stdarg.h>
25
26 #include "gmqcc.h"
27 #include "lexer.h"
28
29 #define PARSER_HT_FIELDS  0
30 #define PARSER_HT_GLOBALS 1
31 /* beginning of locals */
32 #define PARSER_HT_LOCALS  2
33
34 #define PARSER_HT_SIZE    1024
35 #define TYPEDEF_HT_SIZE   16
36
37 typedef struct {
38     lex_file *lex;
39     int      tok;
40
41     ast_expression **globals;
42     ast_expression **fields;
43     ast_function **functions;
44     ast_value    **imm_float;
45     ast_value    **imm_string;
46     ast_value    **imm_vector;
47     size_t         translated;
48
49     /* must be deleted first, they reference immediates and values */
50     ast_value    **accessors;
51
52     ast_value *imm_float_zero;
53     ast_value *imm_float_one;
54     ast_value *imm_vector_zero;
55
56     size_t crc_globals;
57     size_t crc_fields;
58
59     ast_function *function;
60
61     /* All the labels the function defined...
62      * Should they be in ast_function instead?
63      */
64     ast_label **labels;
65     ast_goto  **gotos;
66
67     /* A list of hashtables for each scope */
68     ht *variables;
69     ht htfields;
70     ht htglobals;
71     ht *typedefs;
72
73     /* not to be used directly, we use the hash table */
74     ast_expression **_locals;
75     size_t          *_blocklocals;
76     ast_value      **_typedefs;
77     size_t          *_blocktypedefs;
78     lex_ctx         *_block_ctx;
79
80     size_t errors;
81
82     /* we store the '=' operator info */
83     const oper_info *assign_op;
84
85     /* TYPE_FIELD -> parser_find_fields is used instead of find_var
86      * TODO: TYPE_VECTOR -> x, y and z are accepted in the gmqcc standard
87      * anything else: type error
88      */
89     qcint  memberof;
90
91     /* Keep track of our ternary vs parenthesis nesting state.
92      * If we reach a 'comma' operator in a ternary without a paren,
93      * we shall trigger -Wternary-precedence.
94      */
95     enum { POT_PAREN, POT_TERNARY1, POT_TERNARY2 } *pot;
96
97     /* pragma flags */
98     bool noref;
99 } parser_t;
100
101 static const ast_expression *intrinsic_debug_typestring = (ast_expression*)0x10;
102
103 static void parser_enterblock(parser_t *parser);
104 static bool parser_leaveblock(parser_t *parser);
105 static void parser_addlocal(parser_t *parser, const char *name, ast_expression *e);
106 static bool parse_typedef(parser_t *parser);
107 static bool parse_variable(parser_t *parser, ast_block *localblock, bool nofields, int qualifier, ast_value *cached_typedef, bool noref, bool noreturn);
108 static ast_block* parse_block(parser_t *parser);
109 static bool parse_block_into(parser_t *parser, ast_block *block);
110 static bool parse_statement_or_block(parser_t *parser, ast_expression **out);
111 static bool parse_statement(parser_t *parser, ast_block *block, ast_expression **out, bool allow_cases);
112 static ast_expression* parse_expression_leave(parser_t *parser, bool stopatcomma);
113 static ast_expression* parse_expression(parser_t *parser, bool stopatcomma);
114
115 static void parseerror(parser_t *parser, const char *fmt, ...)
116 {
117         va_list ap;
118
119         parser->errors++;
120
121         va_start(ap, fmt);
122     con_vprintmsg(LVL_ERROR, parser->lex->tok.ctx.file, parser->lex->tok.ctx.line, "parse error", fmt, ap);
123         va_end(ap);
124 }
125
126 /* returns true if it counts as an error */
127 static bool GMQCC_WARN parsewarning(parser_t *parser, int warntype, const char *fmt, ...)
128 {
129     bool    r;
130         va_list ap;
131         va_start(ap, fmt);
132         r = vcompile_warning(parser->lex->tok.ctx, warntype, fmt, ap);
133         va_end(ap);
134         return r;
135 }
136
137 static bool GMQCC_WARN genwarning(lex_ctx ctx, int warntype, const char *fmt, ...)
138 {
139     bool    r;
140         va_list ap;
141         va_start(ap, fmt);
142         r = vcompile_warning(ctx, warntype, fmt, ap);
143         va_end(ap);
144         return r;
145 }
146
147 /**********************************************************************
148  * some maths used for constant folding
149  */
150
151 vector vec3_add(vector a, vector b)
152 {
153     vector out;
154     out.x = a.x + b.x;
155     out.y = a.y + b.y;
156     out.z = a.z + b.z;
157     return out;
158 }
159
160 vector vec3_sub(vector a, vector b)
161 {
162     vector out;
163     out.x = a.x - b.x;
164     out.y = a.y - b.y;
165     out.z = a.z - b.z;
166     return out;
167 }
168
169 qcfloat vec3_mulvv(vector a, vector b)
170 {
171     return (a.x * b.x + a.y * b.y + a.z * b.z);
172 }
173
174 vector vec3_mulvf(vector a, float b)
175 {
176     vector out;
177     out.x = a.x * b;
178     out.y = a.y * b;
179     out.z = a.z * b;
180     return out;
181 }
182
183 /**********************************************************************
184  * parsing
185  */
186
187 bool parser_next(parser_t *parser)
188 {
189     /* lex_do kills the previous token */
190     parser->tok = lex_do(parser->lex);
191     if (parser->tok == TOKEN_EOF)
192         return true;
193     if (parser->tok >= TOKEN_ERROR) {
194         parseerror(parser, "lex error");
195         return false;
196     }
197     return true;
198 }
199
200 #define parser_tokval(p) ((p)->lex->tok.value)
201 #define parser_token(p)  (&((p)->lex->tok))
202 #define parser_ctx(p)    ((p)->lex->tok.ctx)
203
204 static ast_value* parser_const_float(parser_t *parser, double d)
205 {
206     size_t i;
207     ast_value *out;
208     for (i = 0; i < vec_size(parser->imm_float); ++i) {
209         const double compare = parser->imm_float[i]->constval.vfloat;
210         if (memcmp((const void*)&compare, (const void *)&d, sizeof(double)) == 0)
211             return parser->imm_float[i];
212     }
213     out = ast_value_new(parser_ctx(parser), "#IMMEDIATE", TYPE_FLOAT);
214     out->cvq      = CV_CONST;
215     out->hasvalue = true;
216     out->constval.vfloat = d;
217     vec_push(parser->imm_float, out);
218     return out;
219 }
220
221 static ast_value* parser_const_float_0(parser_t *parser)
222 {
223     if (!parser->imm_float_zero)
224         parser->imm_float_zero = parser_const_float(parser, 0);
225     return parser->imm_float_zero;
226 }
227
228 static ast_value* parser_const_float_1(parser_t *parser)
229 {
230     if (!parser->imm_float_one)
231         parser->imm_float_one = parser_const_float(parser, 1);
232     return parser->imm_float_one;
233 }
234
235 static char *parser_strdup(const char *str)
236 {
237     if (str && !*str) {
238         /* actually dup empty strings */
239         char *out = mem_a(1);
240         *out = 0;
241         return out;
242     }
243     return util_strdup(str);
244 }
245
246 static ast_value* parser_const_string(parser_t *parser, const char *str, bool dotranslate)
247 {
248     size_t i;
249     ast_value *out;
250     for (i = 0; i < vec_size(parser->imm_string); ++i) {
251         if (!strcmp(parser->imm_string[i]->constval.vstring, str))
252             return parser->imm_string[i];
253     }
254     if (dotranslate) {
255         char name[32];
256         snprintf(name, sizeof(name), "dotranslate_%lu", (unsigned long)(parser->translated++));
257         out = ast_value_new(parser_ctx(parser), name, TYPE_STRING);
258     } else
259         out = ast_value_new(parser_ctx(parser), "#IMMEDIATE", TYPE_STRING);
260     out->cvq      = CV_CONST;
261     out->hasvalue = true;
262     out->constval.vstring = parser_strdup(str);
263     vec_push(parser->imm_string, out);
264     return out;
265 }
266
267 static ast_value* parser_const_vector(parser_t *parser, vector v)
268 {
269     size_t i;
270     ast_value *out;
271     for (i = 0; i < vec_size(parser->imm_vector); ++i) {
272         if (!memcmp(&parser->imm_vector[i]->constval.vvec, &v, sizeof(v)))
273             return parser->imm_vector[i];
274     }
275     out = ast_value_new(parser_ctx(parser), "#IMMEDIATE", TYPE_VECTOR);
276     out->cvq      = CV_CONST;
277     out->hasvalue = true;
278     out->constval.vvec = v;
279     vec_push(parser->imm_vector, out);
280     return out;
281 }
282
283 static ast_value* parser_const_vector_f(parser_t *parser, float x, float y, float z)
284 {
285     vector v;
286     v.x = x;
287     v.y = y;
288     v.z = z;
289     return parser_const_vector(parser, v);
290 }
291
292 static ast_value* parser_const_vector_0(parser_t *parser)
293 {
294     if (!parser->imm_vector_zero)
295         parser->imm_vector_zero = parser_const_vector_f(parser, 0, 0, 0);
296     return parser->imm_vector_zero;
297 }
298
299 static ast_expression* parser_find_field(parser_t *parser, const char *name)
300 {
301     return util_htget(parser->htfields, name);
302 }
303
304 static ast_expression* parser_find_global(parser_t *parser, const char *name)
305 {
306     return util_htget(parser->htglobals, name);
307 }
308
309 static ast_expression* parser_find_param(parser_t *parser, const char *name)
310 {
311     size_t i;
312     ast_value *fun;
313     if (!parser->function)
314         return NULL;
315     fun = parser->function->vtype;
316     for (i = 0; i < vec_size(fun->expression.params); ++i) {
317         if (!strcmp(fun->expression.params[i]->name, name))
318             return (ast_expression*)(fun->expression.params[i]);
319     }
320     return NULL;
321 }
322
323 static ast_expression* parser_find_local(parser_t *parser, const char *name, size_t upto, bool *isparam)
324 {
325     size_t          i, hash;
326     ast_expression *e;
327
328     hash = util_hthash(parser->htglobals, name);
329
330     *isparam = false;
331     for (i = vec_size(parser->variables); i > upto;) {
332         --i;
333         if ( (e = util_htgeth(parser->variables[i], name, hash)) )
334             return e;
335     }
336     *isparam = true;
337     return parser_find_param(parser, name);
338 }
339
340 static ast_expression* parser_find_var(parser_t *parser, const char *name)
341 {
342     bool dummy;
343     ast_expression *v;
344     v         = parser_find_local(parser, name, 0, &dummy);
345     if (!v) v = parser_find_global(parser, name);
346     return v;
347 }
348
349 static ast_value* parser_find_typedef(parser_t *parser, const char *name, size_t upto)
350 {
351     size_t     i, hash;
352     ast_value *e;
353     hash = util_hthash(parser->typedefs[0], name);
354
355     for (i = vec_size(parser->typedefs); i > upto;) {
356         --i;
357         if ( (e = (ast_value*)util_htgeth(parser->typedefs[i], name, hash)) )
358             return e;
359     }
360     return NULL;
361 }
362
363 typedef struct
364 {
365     size_t etype; /* 0 = expression, others are operators */
366     int             paren;
367     size_t          off;
368     ast_expression *out;
369     ast_block      *block; /* for commas and function calls */
370     lex_ctx ctx;
371 } sy_elem;
372 typedef struct
373 {
374     sy_elem *out;
375     sy_elem *ops;
376 } shunt;
377
378 #define SY_PAREN_EXPR '('
379 #define SY_PAREN_FUNC 'f'
380 #define SY_PAREN_INDEX '['
381 #define SY_PAREN_TERNARY '?'
382
383 static sy_elem syexp(lex_ctx ctx, ast_expression *v) {
384     sy_elem e;
385     e.etype = 0;
386     e.off   = 0;
387     e.out   = v;
388     e.block = NULL;
389     e.ctx   = ctx;
390     e.paren = 0;
391     return e;
392 }
393
394 static sy_elem syblock(lex_ctx ctx, ast_block *v) {
395     sy_elem e;
396     e.etype = 0;
397     e.off   = 0;
398     e.out   = (ast_expression*)v;
399     e.block = v;
400     e.ctx   = ctx;
401     e.paren = 0;
402     return e;
403 }
404
405 static sy_elem syop(lex_ctx ctx, const oper_info *op) {
406     sy_elem e;
407     e.etype = 1 + (op - operators);
408     e.off   = 0;
409     e.out   = NULL;
410     e.block = NULL;
411     e.ctx   = ctx;
412     e.paren = 0;
413     return e;
414 }
415
416 static sy_elem syparen(lex_ctx ctx, int p, size_t off) {
417     sy_elem e;
418     e.etype = 0;
419     e.off   = off;
420     e.out   = NULL;
421     e.block = NULL;
422     e.ctx   = ctx;
423     e.paren = p;
424     return e;
425 }
426
427 #ifdef DEBUGSHUNT
428 # define DEBUGSHUNTDO(x) x
429 #else
430 # define DEBUGSHUNTDO(x)
431 #endif
432
433 /* With regular precedence rules, ent.foo[n] is the same as (ent.foo)[n],
434  * so we need to rotate it to become ent.(foo[n]).
435  */
436 static bool rotate_entfield_array_index_nodes(ast_expression **out)
437 {
438     ast_array_index *index;
439     ast_entfield    *entfield;
440
441     ast_value       *field;
442     ast_expression  *sub;
443     ast_expression  *entity;
444
445     lex_ctx ctx = ast_ctx(*out);
446
447     if (!ast_istype(*out, ast_array_index))
448         return false;
449     index = (ast_array_index*)*out;
450
451     if (!ast_istype(index->array, ast_entfield))
452         return false;
453     entfield = (ast_entfield*)index->array;
454
455     if (!ast_istype(entfield->field, ast_value))
456         return false;
457     field = (ast_value*)entfield->field;
458
459     sub    = index->index;
460     entity = entfield->entity;
461
462     ast_delete(index);
463
464     index = ast_array_index_new(ctx, (ast_expression*)field, sub);
465     entfield = ast_entfield_new(ctx, entity, (ast_expression*)index);
466     *out = (ast_expression*)entfield;
467
468     return true;
469 }
470
471 static bool parser_sy_apply_operator(parser_t *parser, shunt *sy)
472 {
473     const oper_info *op;
474     lex_ctx ctx;
475     ast_expression *out = NULL;
476     ast_expression *exprs[3];
477     ast_block      *blocks[3];
478     ast_value      *asvalue[3];
479     ast_binstore   *asbinstore;
480     size_t i, assignop, addop, subop;
481     qcint  generated_op = 0;
482
483     char ty1[1024];
484     char ty2[1024];
485
486     if (!vec_size(sy->ops)) {
487         parseerror(parser, "internal error: missing operator");
488         return false;
489     }
490
491     if (vec_last(sy->ops).paren) {
492         parseerror(parser, "unmatched parenthesis");
493         return false;
494     }
495
496     op = &operators[vec_last(sy->ops).etype - 1];
497     ctx = vec_last(sy->ops).ctx;
498
499     DEBUGSHUNTDO(con_out("apply %s\n", op->op));
500
501     if (vec_size(sy->out) < op->operands) {
502         parseerror(parser, "internal error: not enough operands: %i (operator %s (%i))", vec_size(sy->out),
503                    op->op, (int)op->id);
504         return false;
505     }
506
507     vec_shrinkby(sy->ops, 1);
508
509     /* op(:?) has no input and no output */
510     if (!op->operands)
511         return true;
512
513     vec_shrinkby(sy->out, op->operands);
514     for (i = 0; i < op->operands; ++i) {
515         exprs[i]  = sy->out[vec_size(sy->out)+i].out;
516         blocks[i] = sy->out[vec_size(sy->out)+i].block;
517         asvalue[i] = (ast_value*)exprs[i];
518     }
519
520     if (blocks[0] && !vec_size(blocks[0]->exprs) && op->id != opid1(',')) {
521         parseerror(parser, "internal error: operator cannot be applied on empty blocks");
522         return false;
523     }
524
525 #define NotSameType(T) \
526              (exprs[0]->expression.vtype != exprs[1]->expression.vtype || \
527               exprs[0]->expression.vtype != T)
528 #define CanConstFold1(A) \
529              (ast_istype((A), ast_value) && ((ast_value*)(A))->hasvalue && (((ast_value*)(A))->cvq == CV_CONST))
530 #define CanConstFold(A, B) \
531              (CanConstFold1(A) && CanConstFold1(B))
532 #define ConstV(i) (asvalue[(i)]->constval.vvec)
533 #define ConstF(i) (asvalue[(i)]->constval.vfloat)
534 #define ConstS(i) (asvalue[(i)]->constval.vstring)
535     switch (op->id)
536     {
537         default:
538             parseerror(parser, "internal error: unhandled operator: %s (%i)", op->op, (int)op->id);
539             return false;
540
541         case opid1('.'):
542             if (exprs[0]->expression.vtype == TYPE_ENTITY) {
543                 if (exprs[1]->expression.vtype != TYPE_FIELD) {
544                     parseerror(parser, "type error: right hand of member-operand should be an entity-field");
545                     return false;
546                 }
547                 out = (ast_expression*)ast_entfield_new(ctx, exprs[0], exprs[1]);
548             }
549             else if (exprs[0]->expression.vtype == TYPE_VECTOR) {
550                 parseerror(parser, "internal error: vector access is not supposed to be handled at this point");
551                 return false;
552             }
553             else {
554                 parseerror(parser, "type error: member-of operator on something that is not an entity or vector");
555                 return false;
556             }
557             break;
558
559         case opid1('['):
560             if (exprs[0]->expression.vtype != TYPE_ARRAY &&
561                 !(exprs[0]->expression.vtype == TYPE_FIELD &&
562                   exprs[0]->expression.next->expression.vtype == TYPE_ARRAY))
563             {
564                 ast_type_to_string(exprs[0], ty1, sizeof(ty1));
565                 parseerror(parser, "cannot index value of type %s", ty1);
566                 return false;
567             }
568             if (exprs[1]->expression.vtype != TYPE_FLOAT) {
569                 ast_type_to_string(exprs[0], ty1, sizeof(ty1));
570                 parseerror(parser, "index must be of type float, not %s", ty1);
571                 return false;
572             }
573             out = (ast_expression*)ast_array_index_new(ctx, exprs[0], exprs[1]);
574             if (rotate_entfield_array_index_nodes(&out))
575             {
576 #if 0
577                 /* This is not broken in fteqcc anymore */
578                 if (opts.standard != COMPILER_GMQCC) {
579                     /* this error doesn't need to make us bail out */
580                     (void)!parsewarning(parser, WARN_EXTENSIONS,
581                                         "accessing array-field members of an entity without parenthesis\n"
582                                         " -> this is an extension from -std=gmqcc");
583                 }
584 #endif
585             }
586             break;
587
588         case opid1(','):
589             if (blocks[0]) {
590                 if (!ast_block_add_expr(blocks[0], exprs[1]))
591                     return false;
592             } else {
593                 blocks[0] = ast_block_new(ctx);
594                 if (!ast_block_add_expr(blocks[0], exprs[0]) ||
595                     !ast_block_add_expr(blocks[0], exprs[1]))
596                 {
597                     return false;
598                 }
599             }
600             if (!ast_block_set_type(blocks[0], exprs[1]))
601                 return false;
602
603             vec_push(sy->out, syblock(ctx, blocks[0]));
604             return true;
605
606         case opid2('+','P'):
607             out = exprs[0];
608             break;
609         case opid2('-','P'):
610             switch (exprs[0]->expression.vtype) {
611                 case TYPE_FLOAT:
612                     if (CanConstFold1(exprs[0]))
613                         out = (ast_expression*)parser_const_float(parser, -ConstF(0));
614                     else
615                         out = (ast_expression*)ast_binary_new(ctx, INSTR_SUB_F,
616                                                               (ast_expression*)parser_const_float_0(parser),
617                                                               exprs[0]);
618                     break;
619                 case TYPE_VECTOR:
620                     if (CanConstFold1(exprs[0]))
621                         out = (ast_expression*)parser_const_vector_f(parser,
622                             -ConstV(0).x, -ConstV(0).y, -ConstV(0).z);
623                     else
624                         out = (ast_expression*)ast_binary_new(ctx, INSTR_SUB_V,
625                                                               (ast_expression*)parser_const_vector_0(parser),
626                                                               exprs[0]);
627                     break;
628                 default:
629                 parseerror(parser, "invalid types used in expression: cannot negate type %s",
630                            type_name[exprs[0]->expression.vtype]);
631                 return false;
632             }
633             break;
634
635         case opid2('!','P'):
636             switch (exprs[0]->expression.vtype) {
637                 case TYPE_FLOAT:
638                     if (CanConstFold1(exprs[0]))
639                         out = (ast_expression*)parser_const_float(parser, !ConstF(0));
640                     else
641                         out = (ast_expression*)ast_unary_new(ctx, INSTR_NOT_F, exprs[0]);
642                     break;
643                 case TYPE_VECTOR:
644                     if (CanConstFold1(exprs[0]))
645                         out = (ast_expression*)parser_const_float(parser,
646                             (!ConstV(0).x && !ConstV(0).y && !ConstV(0).z));
647                     else
648                         out = (ast_expression*)ast_unary_new(ctx, INSTR_NOT_V, exprs[0]);
649                     break;
650                 case TYPE_STRING:
651                     if (CanConstFold1(exprs[0]))
652                         out = (ast_expression*)parser_const_float(parser, !ConstS(0) || !*ConstS(0));
653                     else
654                         out = (ast_expression*)ast_unary_new(ctx, INSTR_NOT_S, exprs[0]);
655                     break;
656                 /* we don't constant-fold NOT for these types */
657                 case TYPE_ENTITY:
658                     out = (ast_expression*)ast_unary_new(ctx, INSTR_NOT_ENT, exprs[0]);
659                     break;
660                 case TYPE_FUNCTION:
661                     out = (ast_expression*)ast_unary_new(ctx, INSTR_NOT_FNC, exprs[0]);
662                     break;
663                 default:
664                 parseerror(parser, "invalid types used in expression: cannot logically negate type %s",
665                            type_name[exprs[0]->expression.vtype]);
666                 return false;
667             }
668             break;
669
670         case opid1('+'):
671             if (exprs[0]->expression.vtype != exprs[1]->expression.vtype ||
672                 (exprs[0]->expression.vtype != TYPE_VECTOR && exprs[0]->expression.vtype != TYPE_FLOAT) )
673             {
674                 parseerror(parser, "invalid types used in expression: cannot add type %s and %s",
675                            type_name[exprs[0]->expression.vtype],
676                            type_name[exprs[1]->expression.vtype]);
677                 return false;
678             }
679             switch (exprs[0]->expression.vtype) {
680                 case TYPE_FLOAT:
681                     if (CanConstFold(exprs[0], exprs[1]))
682                     {
683                         out = (ast_expression*)parser_const_float(parser, ConstF(0) + ConstF(1));
684                     }
685                     else
686                         out = (ast_expression*)ast_binary_new(ctx, INSTR_ADD_F, exprs[0], exprs[1]);
687                     break;
688                 case TYPE_VECTOR:
689                     if (CanConstFold(exprs[0], exprs[1]))
690                         out = (ast_expression*)parser_const_vector(parser, vec3_add(ConstV(0), ConstV(1)));
691                     else
692                         out = (ast_expression*)ast_binary_new(ctx, INSTR_ADD_V, exprs[0], exprs[1]);
693                     break;
694                 default:
695                     parseerror(parser, "invalid types used in expression: cannot add type %s and %s",
696                                type_name[exprs[0]->expression.vtype],
697                                type_name[exprs[1]->expression.vtype]);
698                     return false;
699             };
700             break;
701         case opid1('-'):
702             if (exprs[0]->expression.vtype != exprs[1]->expression.vtype ||
703                 (exprs[0]->expression.vtype != TYPE_VECTOR && exprs[0]->expression.vtype != TYPE_FLOAT) )
704             {
705                 parseerror(parser, "invalid types used in expression: cannot subtract type %s from %s",
706                            type_name[exprs[1]->expression.vtype],
707                            type_name[exprs[0]->expression.vtype]);
708                 return false;
709             }
710             switch (exprs[0]->expression.vtype) {
711                 case TYPE_FLOAT:
712                     if (CanConstFold(exprs[0], exprs[1]))
713                         out = (ast_expression*)parser_const_float(parser, ConstF(0) - ConstF(1));
714                     else
715                         out = (ast_expression*)ast_binary_new(ctx, INSTR_SUB_F, exprs[0], exprs[1]);
716                     break;
717                 case TYPE_VECTOR:
718                     if (CanConstFold(exprs[0], exprs[1]))
719                         out = (ast_expression*)parser_const_vector(parser, vec3_sub(ConstV(0), ConstV(1)));
720                     else
721                         out = (ast_expression*)ast_binary_new(ctx, INSTR_SUB_V, exprs[0], exprs[1]);
722                     break;
723                 default:
724                     parseerror(parser, "invalid types used in expression: cannot subtract type %s from %s",
725                                type_name[exprs[1]->expression.vtype],
726                                type_name[exprs[0]->expression.vtype]);
727                     return false;
728             };
729             break;
730         case opid1('*'):
731             if (exprs[0]->expression.vtype != exprs[1]->expression.vtype &&
732                 exprs[0]->expression.vtype != TYPE_VECTOR &&
733                 exprs[0]->expression.vtype != TYPE_FLOAT &&
734                 exprs[1]->expression.vtype != TYPE_VECTOR &&
735                 exprs[1]->expression.vtype != TYPE_FLOAT)
736             {
737                 parseerror(parser, "invalid types used in expression: cannot multiply types %s and %s",
738                            type_name[exprs[1]->expression.vtype],
739                            type_name[exprs[0]->expression.vtype]);
740                 return false;
741             }
742             switch (exprs[0]->expression.vtype) {
743                 case TYPE_FLOAT:
744                     if (exprs[1]->expression.vtype == TYPE_VECTOR)
745                     {
746                         if (CanConstFold(exprs[0], exprs[1]))
747                             out = (ast_expression*)parser_const_vector(parser, vec3_mulvf(ConstV(1), ConstF(0)));
748                         else
749                             out = (ast_expression*)ast_binary_new(ctx, INSTR_MUL_FV, exprs[0], exprs[1]);
750                     }
751                     else
752                     {
753                         if (CanConstFold(exprs[0], exprs[1]))
754                             out = (ast_expression*)parser_const_float(parser, ConstF(0) * ConstF(1));
755                         else
756                             out = (ast_expression*)ast_binary_new(ctx, INSTR_MUL_F, exprs[0], exprs[1]);
757                     }
758                     break;
759                 case TYPE_VECTOR:
760                     if (exprs[1]->expression.vtype == TYPE_FLOAT)
761                     {
762                         if (CanConstFold(exprs[0], exprs[1]))
763                             out = (ast_expression*)parser_const_vector(parser, vec3_mulvf(ConstV(0), ConstF(1)));
764                         else
765                             out = (ast_expression*)ast_binary_new(ctx, INSTR_MUL_VF, exprs[0], exprs[1]);
766                     }
767                     else
768                     {
769                         if (CanConstFold(exprs[0], exprs[1]))
770                             out = (ast_expression*)parser_const_float(parser, vec3_mulvv(ConstV(0), ConstV(1)));
771                         else
772                             out = (ast_expression*)ast_binary_new(ctx, INSTR_MUL_V, exprs[0], exprs[1]);
773                     }
774                     break;
775                 default:
776                     parseerror(parser, "invalid types used in expression: cannot multiply types %s and %s",
777                                type_name[exprs[1]->expression.vtype],
778                                type_name[exprs[0]->expression.vtype]);
779                     return false;
780             };
781             break;
782         case opid1('/'):
783             if (NotSameType(TYPE_FLOAT)) {
784                 parseerror(parser, "invalid types used in expression: cannot divide types %s and %s",
785                            type_name[exprs[0]->expression.vtype],
786                            type_name[exprs[1]->expression.vtype]);
787                 return false;
788             }
789             if (CanConstFold(exprs[0], exprs[1]))
790                 out = (ast_expression*)parser_const_float(parser, ConstF(0) / ConstF(1));
791             else
792                 out = (ast_expression*)ast_binary_new(ctx, INSTR_DIV_F, exprs[0], exprs[1]);
793             break;
794         case opid1('%'):
795         case opid2('%','='):
796             parseerror(parser, "qc does not have a modulo operator");
797             return false;
798         case opid1('|'):
799         case opid1('&'):
800             if (NotSameType(TYPE_FLOAT)) {
801                 parseerror(parser, "invalid types used in expression: cannot perform bit operations between types %s and %s",
802                            type_name[exprs[0]->expression.vtype],
803                            type_name[exprs[1]->expression.vtype]);
804                 return false;
805             }
806             if (CanConstFold(exprs[0], exprs[1]))
807                 out = (ast_expression*)parser_const_float(parser,
808                     (op->id == opid1('|') ? (float)( ((qcint)ConstF(0)) | ((qcint)ConstF(1)) ) :
809                                             (float)( ((qcint)ConstF(0)) & ((qcint)ConstF(1)) ) ));
810             else
811                 out = (ast_expression*)ast_binary_new(ctx,
812                     (op->id == opid1('|') ? INSTR_BITOR : INSTR_BITAND),
813                     exprs[0], exprs[1]);
814             break;
815         case opid1('^'):
816             parseerror(parser, "TODO: bitxor");
817             return false;
818
819         case opid2('<','<'):
820         case opid2('>','>'):
821         case opid3('<','<','='):
822         case opid3('>','>','='):
823             parseerror(parser, "TODO: shifts");
824             return false;
825
826         case opid2('|','|'):
827             generated_op += 1; /* INSTR_OR */
828         case opid2('&','&'):
829             generated_op += INSTR_AND;
830 #if 0
831             if (NotSameType(TYPE_FLOAT)) {
832                 parseerror(parser, "invalid types used in expression: cannot perform logical operations between types %s and %s",
833                            type_name[exprs[0]->expression.vtype],
834                            type_name[exprs[1]->expression.vtype]);
835                 parseerror(parser, "TODO: logical ops for arbitrary types using INSTR_NOT");
836                 parseerror(parser, "TODO: optional early out");
837                 return false;
838             }
839 #endif
840             if (CanConstFold(exprs[0], exprs[1]))
841             {
842                 out = (ast_expression*)parser_const_float(parser,
843                     (generated_op == INSTR_OR ? (ConstF(0) || ConstF(1)) : (ConstF(0) && ConstF(1))));
844             }
845             else
846             {
847                 if (OPTS_FLAG(PERL_LOGIC) && !ast_compare_type(exprs[0], exprs[1])) {
848                     ast_type_to_string(exprs[0], ty1, sizeof(ty1));
849                     ast_type_to_string(exprs[1], ty2, sizeof(ty2));
850                     parseerror(parser, "invalid types for logical operation with -fperl-logic: %s and %s", ty1, ty2);
851                     return false;
852                 }
853                 if (OPTS_FLAG(CORRECT_LOGIC)) {
854                     /* non-floats need to be NOTed */
855                     for (i = 0; i < 2; ++i) {
856                         if (exprs[i]->expression.vtype != TYPE_FLOAT) {
857                             if (type_not_instr[exprs[i]->expression.vtype] == AINSTR_END) {
858                                 ast_type_to_string(exprs[0], ty1, sizeof(ty1));
859                                 ast_type_to_string(exprs[1], ty2, sizeof(ty2));
860                                 parseerror(parser, "invalid types for logical operation with -fcorrect-logic: %s and %s", ty1, ty2);
861                                 return false;
862                             }
863                             out = (ast_expression*)ast_unary_new(ctx, type_not_instr[exprs[i]->expression.vtype], exprs[i]);
864                             if (!out)
865                                 break;
866                             exprs[i] = out; out = NULL;
867                         }
868                         if (OPTS_FLAG(PERL_LOGIC))
869                             break;
870                     }
871                 }
872                 out = (ast_expression*)ast_binary_new(ctx, generated_op, exprs[0], exprs[1]);
873             }
874             break;
875
876         case opid2('?',':'):
877             if (vec_last(parser->pot) != POT_TERNARY2) {
878                 parseerror(parser, "mismatched parenthesis/ternary");
879                 return false;
880             }
881             vec_pop(parser->pot);
882             if (exprs[1]->expression.vtype != exprs[2]->expression.vtype) {
883                 ast_type_to_string(exprs[1], ty1, sizeof(ty1));
884                 ast_type_to_string(exprs[2], ty2, sizeof(ty2));
885                 parseerror(parser, "operands of ternary expression must have the same type, got %s and %s", ty1, ty2);
886                 return false;
887             }
888             if (CanConstFold1(exprs[0]))
889                 out = (ConstF(0) ? exprs[1] : exprs[2]);
890             else
891                 out = (ast_expression*)ast_ternary_new(ctx, exprs[0], exprs[1], exprs[2]);
892             break;
893
894         case opid1('>'):
895             generated_op += 1; /* INSTR_GT */
896         case opid1('<'):
897             generated_op += 1; /* INSTR_LT */
898         case opid2('>', '='):
899             generated_op += 1; /* INSTR_GE */
900         case opid2('<', '='):
901             generated_op += INSTR_LE;
902             if (NotSameType(TYPE_FLOAT)) {
903                 parseerror(parser, "invalid types used in expression: cannot perform comparison between types %s and %s",
904                            type_name[exprs[0]->expression.vtype],
905                            type_name[exprs[1]->expression.vtype]);
906                 return false;
907             }
908             out = (ast_expression*)ast_binary_new(ctx, generated_op, exprs[0], exprs[1]);
909             break;
910         case opid2('!', '='):
911             if (exprs[0]->expression.vtype != exprs[1]->expression.vtype) {
912                 parseerror(parser, "invalid types used in expression: cannot perform comparison between types %s and %s",
913                            type_name[exprs[0]->expression.vtype],
914                            type_name[exprs[1]->expression.vtype]);
915                 return false;
916             }
917             out = (ast_expression*)ast_binary_new(ctx, type_ne_instr[exprs[0]->expression.vtype], exprs[0], exprs[1]);
918             break;
919         case opid2('=', '='):
920             if (exprs[0]->expression.vtype != exprs[1]->expression.vtype) {
921                 parseerror(parser, "invalid types used in expression: cannot perform comparison between types %s and %s",
922                            type_name[exprs[0]->expression.vtype],
923                            type_name[exprs[1]->expression.vtype]);
924                 return false;
925             }
926             out = (ast_expression*)ast_binary_new(ctx, type_eq_instr[exprs[0]->expression.vtype], exprs[0], exprs[1]);
927             break;
928
929         case opid1('='):
930             if (ast_istype(exprs[0], ast_entfield)) {
931                 ast_expression *field = ((ast_entfield*)exprs[0])->field;
932                 if (OPTS_FLAG(ADJUST_VECTOR_FIELDS) &&
933                     exprs[0]->expression.vtype == TYPE_FIELD &&
934                     exprs[0]->expression.next->expression.vtype == TYPE_VECTOR)
935                 {
936                     assignop = type_storep_instr[TYPE_VECTOR];
937                 }
938                 else
939                     assignop = type_storep_instr[exprs[0]->expression.vtype];
940                 if (assignop == AINSTR_END ||
941                     !ast_compare_type(field->expression.next, exprs[1]))
942                 {
943                     ast_type_to_string(field->expression.next, ty1, sizeof(ty1));
944                     ast_type_to_string(exprs[1], ty2, sizeof(ty2));
945                     if (OPTS_FLAG(ASSIGN_FUNCTION_TYPES) &&
946                         field->expression.next->expression.vtype == TYPE_FUNCTION &&
947                         exprs[1]->expression.vtype == TYPE_FUNCTION)
948                     {
949                         if (parsewarning(parser, WARN_ASSIGN_FUNCTION_TYPES,
950                                          "invalid types in assignment: cannot assign %s to %s", ty2, ty1))
951                         {
952                             parser->errors++;
953                         }
954                     }
955                     else
956                         parseerror(parser, "invalid types in assignment: cannot assign %s to %s", ty2, ty1);
957                 }
958             }
959             else
960             {
961                 if (OPTS_FLAG(ADJUST_VECTOR_FIELDS) &&
962                     exprs[0]->expression.vtype == TYPE_FIELD &&
963                     exprs[0]->expression.next->expression.vtype == TYPE_VECTOR)
964                 {
965                     assignop = type_store_instr[TYPE_VECTOR];
966                 }
967                 else {
968                     assignop = type_store_instr[exprs[0]->expression.vtype];
969                 }
970
971                 if (assignop == AINSTR_END) {
972                     ast_type_to_string(exprs[0], ty1, sizeof(ty1));
973                     ast_type_to_string(exprs[1], ty2, sizeof(ty2));
974                     parseerror(parser, "invalid types in assignment: cannot assign %s to %s", ty2, ty1);
975                 }
976                 else if (!ast_compare_type(exprs[0], exprs[1])) {
977                     ast_type_to_string(exprs[0], ty1, sizeof(ty1));
978                     ast_type_to_string(exprs[1], ty2, sizeof(ty2));
979                     if (OPTS_FLAG(ASSIGN_FUNCTION_TYPES) &&
980                         exprs[0]->expression.vtype == TYPE_FUNCTION &&
981                         exprs[1]->expression.vtype == TYPE_FUNCTION)
982                     {
983                         if (parsewarning(parser, WARN_ASSIGN_FUNCTION_TYPES,
984                                          "invalid types in assignment: cannot assign %s to %s", ty2, ty1))
985                         {
986                             parser->errors++;
987                         }
988                     }
989                     else
990                         parseerror(parser, "invalid types in assignment: cannot assign %s to %s", ty2, ty1);
991                 }
992             }
993             if (ast_istype(exprs[0], ast_value) && asvalue[0]->cvq == CV_CONST) {
994                 parseerror(parser, "assignment to constant `%s`", asvalue[0]->name);
995             }
996             out = (ast_expression*)ast_store_new(ctx, assignop, exprs[0], exprs[1]);
997             break;
998         case opid3('+','+','P'):
999         case opid3('-','-','P'):
1000             /* prefix ++ */
1001             if (exprs[0]->expression.vtype != TYPE_FLOAT) {
1002                 ast_type_to_string(exprs[0], ty1, sizeof(ty1));
1003                 parseerror(parser, "invalid type for prefix increment: %s", ty1);
1004                 return false;
1005             }
1006             if (op->id == opid3('+','+','P'))
1007                 addop = INSTR_ADD_F;
1008             else
1009                 addop = INSTR_SUB_F;
1010             if (ast_istype(exprs[0], ast_value) && asvalue[0]->cvq == CV_CONST) {
1011                 parseerror(parser, "assignment to constant `%s`", asvalue[0]->name);
1012             }
1013             if (ast_istype(exprs[0], ast_entfield)) {
1014                 out = (ast_expression*)ast_binstore_new(ctx, INSTR_STOREP_F, addop,
1015                                                         exprs[0],
1016                                                         (ast_expression*)parser_const_float_1(parser));
1017             } else {
1018                 out = (ast_expression*)ast_binstore_new(ctx, INSTR_STORE_F, addop,
1019                                                         exprs[0],
1020                                                         (ast_expression*)parser_const_float_1(parser));
1021             }
1022             break;
1023         case opid3('S','+','+'):
1024         case opid3('S','-','-'):
1025             /* prefix ++ */
1026             if (exprs[0]->expression.vtype != TYPE_FLOAT) {
1027                 ast_type_to_string(exprs[0], ty1, sizeof(ty1));
1028                 parseerror(parser, "invalid type for suffix increment: %s", ty1);
1029                 return false;
1030             }
1031             if (op->id == opid3('S','+','+')) {
1032                 addop = INSTR_ADD_F;
1033                 subop = INSTR_SUB_F;
1034             } else {
1035                 addop = INSTR_SUB_F;
1036                 subop = INSTR_ADD_F;
1037             }
1038             if (ast_istype(exprs[0], ast_value) && asvalue[0]->cvq == CV_CONST) {
1039                 parseerror(parser, "assignment to constant `%s`", asvalue[0]->name);
1040             }
1041             if (ast_istype(exprs[0], ast_entfield)) {
1042                 out = (ast_expression*)ast_binstore_new(ctx, INSTR_STOREP_F, addop,
1043                                                         exprs[0],
1044                                                         (ast_expression*)parser_const_float_1(parser));
1045             } else {
1046                 out = (ast_expression*)ast_binstore_new(ctx, INSTR_STORE_F, addop,
1047                                                         exprs[0],
1048                                                         (ast_expression*)parser_const_float_1(parser));
1049             }
1050             if (!out)
1051                 return false;
1052             out = (ast_expression*)ast_binary_new(ctx, subop,
1053                                                   out,
1054                                                   (ast_expression*)parser_const_float_1(parser));
1055             break;
1056         case opid2('+','='):
1057         case opid2('-','='):
1058             if (exprs[0]->expression.vtype != exprs[1]->expression.vtype ||
1059                 (exprs[0]->expression.vtype != TYPE_VECTOR && exprs[0]->expression.vtype != TYPE_FLOAT) )
1060             {
1061                 ast_type_to_string(exprs[0], ty1, sizeof(ty1));
1062                 ast_type_to_string(exprs[1], ty2, sizeof(ty2));
1063                 parseerror(parser, "invalid types used in expression: cannot add or subtract type %s and %s",
1064                            ty1, ty2);
1065                 return false;
1066             }
1067             if (ast_istype(exprs[0], ast_value) && asvalue[0]->cvq == CV_CONST) {
1068                 parseerror(parser, "assignment to constant `%s`", asvalue[0]->name);
1069             }
1070             if (ast_istype(exprs[0], ast_entfield))
1071                 assignop = type_storep_instr[exprs[0]->expression.vtype];
1072             else
1073                 assignop = type_store_instr[exprs[0]->expression.vtype];
1074             switch (exprs[0]->expression.vtype) {
1075                 case TYPE_FLOAT:
1076                     out = (ast_expression*)ast_binstore_new(ctx, assignop,
1077                                                             (op->id == opid2('+','=') ? INSTR_ADD_F : INSTR_SUB_F),
1078                                                             exprs[0], exprs[1]);
1079                     break;
1080                 case TYPE_VECTOR:
1081                     out = (ast_expression*)ast_binstore_new(ctx, assignop,
1082                                                             (op->id == opid2('+','=') ? INSTR_ADD_V : INSTR_SUB_V),
1083                                                             exprs[0], exprs[1]);
1084                     break;
1085                 default:
1086                     parseerror(parser, "invalid types used in expression: cannot add or subtract type %s and %s",
1087                                type_name[exprs[0]->expression.vtype],
1088                                type_name[exprs[1]->expression.vtype]);
1089                     return false;
1090             };
1091             break;
1092         case opid2('*','='):
1093         case opid2('/','='):
1094             if (exprs[1]->expression.vtype != TYPE_FLOAT ||
1095                 !(exprs[0]->expression.vtype == TYPE_FLOAT ||
1096                   exprs[0]->expression.vtype == TYPE_VECTOR))
1097             {
1098                 ast_type_to_string(exprs[0], ty1, sizeof(ty1));
1099                 ast_type_to_string(exprs[1], ty2, sizeof(ty2));
1100                 parseerror(parser, "invalid types used in expression: %s and %s",
1101                            ty1, ty2);
1102                 return false;
1103             }
1104             if (ast_istype(exprs[0], ast_value) && asvalue[0]->cvq == CV_CONST) {
1105                 parseerror(parser, "assignment to constant `%s`", asvalue[0]->name);
1106             }
1107             if (ast_istype(exprs[0], ast_entfield))
1108                 assignop = type_storep_instr[exprs[0]->expression.vtype];
1109             else
1110                 assignop = type_store_instr[exprs[0]->expression.vtype];
1111             switch (exprs[0]->expression.vtype) {
1112                 case TYPE_FLOAT:
1113                     out = (ast_expression*)ast_binstore_new(ctx, assignop,
1114                                                             (op->id == opid2('*','=') ? INSTR_MUL_F : INSTR_DIV_F),
1115                                                             exprs[0], exprs[1]);
1116                     break;
1117                 case TYPE_VECTOR:
1118                     if (op->id == opid2('*','=')) {
1119                         out = (ast_expression*)ast_binstore_new(ctx, assignop, INSTR_MUL_VF,
1120                                                                 exprs[0], exprs[1]);
1121                     } else {
1122                         /* there's no DIV_VF */
1123                         out = (ast_expression*)ast_binary_new(ctx, INSTR_DIV_F,
1124                                                               (ast_expression*)parser_const_float_1(parser),
1125                                                               exprs[1]);
1126                         if (!out)
1127                             return false;
1128                         out = (ast_expression*)ast_binstore_new(ctx, assignop, INSTR_MUL_VF,
1129                                                                 exprs[0], out);
1130                     }
1131                     break;
1132                 default:
1133                     parseerror(parser, "invalid types used in expression: cannot add or subtract type %s and %s",
1134                                type_name[exprs[0]->expression.vtype],
1135                                type_name[exprs[1]->expression.vtype]);
1136                     return false;
1137             };
1138             break;
1139         case opid2('&','='):
1140         case opid2('|','='):
1141             if (NotSameType(TYPE_FLOAT)) {
1142                 ast_type_to_string(exprs[0], ty1, sizeof(ty1));
1143                 ast_type_to_string(exprs[1], ty2, sizeof(ty2));
1144                 parseerror(parser, "invalid types used in expression: %s and %s",
1145                            ty1, ty2);
1146                 return false;
1147             }
1148             if (ast_istype(exprs[0], ast_value) && asvalue[0]->cvq == CV_CONST) {
1149                 parseerror(parser, "assignment to constant `%s`", asvalue[0]->name);
1150             }
1151             if (ast_istype(exprs[0], ast_entfield))
1152                 assignop = type_storep_instr[exprs[0]->expression.vtype];
1153             else
1154                 assignop = type_store_instr[exprs[0]->expression.vtype];
1155             out = (ast_expression*)ast_binstore_new(ctx, assignop,
1156                                                     (op->id == opid2('&','=') ? INSTR_BITAND : INSTR_BITOR),
1157                                                     exprs[0], exprs[1]);
1158             break;
1159         case opid3('&','~','='):
1160             /* This is like: a &= ~(b);
1161              * But QC has no bitwise-not, so we implement it as
1162              * a -= a & (b);
1163              */
1164             if (NotSameType(TYPE_FLOAT)) {
1165                 ast_type_to_string(exprs[0], ty1, sizeof(ty1));
1166                 ast_type_to_string(exprs[1], ty2, sizeof(ty2));
1167                 parseerror(parser, "invalid types used in expression: %s and %s",
1168                            ty1, ty2);
1169                 return false;
1170             }
1171             if (ast_istype(exprs[0], ast_entfield))
1172                 assignop = type_storep_instr[exprs[0]->expression.vtype];
1173             else
1174                 assignop = type_store_instr[exprs[0]->expression.vtype];
1175             out = (ast_expression*)ast_binary_new(ctx, INSTR_BITAND, exprs[0], exprs[1]);
1176             if (!out)
1177                 return false;
1178             if (ast_istype(exprs[0], ast_value) && asvalue[0]->cvq == CV_CONST) {
1179                 parseerror(parser, "assignment to constant `%s`", asvalue[0]->name);
1180             }
1181             asbinstore = ast_binstore_new(ctx, assignop, INSTR_SUB_F, exprs[0], out);
1182             asbinstore->keep_dest = true;
1183             out = (ast_expression*)asbinstore;
1184             break;
1185     }
1186 #undef NotSameType
1187
1188     if (!out) {
1189         parseerror(parser, "failed to apply operand %s", op->op);
1190         return false;
1191     }
1192
1193     DEBUGSHUNTDO(con_out("applied %s\n", op->op));
1194     vec_push(sy->out, syexp(ctx, out));
1195     return true;
1196 }
1197
1198 static bool parser_close_call(parser_t *parser, shunt *sy)
1199 {
1200     /* was a function call */
1201     ast_expression *fun;
1202     ast_call       *call;
1203
1204     size_t          fid;
1205     size_t          paramcount;
1206
1207     vec_shrinkby(sy->ops, 1);
1208     fid = sy->ops[vec_size(sy->ops)].off;
1209
1210     /* out[fid] is the function
1211      * everything above is parameters...
1212      * 0 params = nothing
1213      * 1 params = ast_expression
1214      * more = ast_block
1215      */
1216
1217     if (vec_size(sy->out) < 1 || vec_size(sy->out) <= fid) {
1218         parseerror(parser, "internal error: function call needs function and parameter list...");
1219         return false;
1220     }
1221
1222     fun = sy->out[fid].out;
1223
1224     if (fun == intrinsic_debug_typestring) {
1225         char ty[1024];
1226         if (fid+2 != vec_size(sy->out) ||
1227             vec_last(sy->out).block)
1228         {
1229             parseerror(parser, "intrinsic __builtin_debug_typestring requires exactly 1 parameter");
1230             return false;
1231         }
1232         ast_type_to_string(vec_last(sy->out).out, ty, sizeof(ty));
1233         ast_unref(vec_last(sy->out).out);
1234         sy->out[fid] = syexp(ast_ctx(vec_last(sy->out).out),
1235                              (ast_expression*)parser_const_string(parser, ty, false));
1236         vec_shrinkby(sy->out, 1);
1237         return true;
1238     }
1239
1240     call = ast_call_new(sy->ops[vec_size(sy->ops)].ctx, fun);
1241     if (!call) {
1242         parseerror(parser, "internal error: failed to create ast_call node");
1243         return false;
1244     }
1245
1246     if (fid+1 == vec_size(sy->out)) {
1247         /* no arguments */
1248         paramcount = 0;
1249     } else if (fid+2 == vec_size(sy->out)) {
1250         ast_block *params;
1251         vec_shrinkby(sy->out, 1);
1252         params = sy->out[vec_size(sy->out)].block;
1253         if (!params) {
1254             /* 1 param */
1255             paramcount = 1;
1256             vec_push(call->params, sy->out[vec_size(sy->out)].out);
1257         } else {
1258             paramcount = vec_size(params->exprs);
1259             call->params = params->exprs;
1260             params->exprs = NULL;
1261             ast_delete(params);
1262         }
1263         if (!ast_call_check_types(call))
1264             parser->errors++;
1265     } else {
1266         parseerror(parser, "invalid function call");
1267         return false;
1268     }
1269
1270     /* overwrite fid, the function, with a call */
1271     sy->out[fid] = syexp(call->expression.node.context, (ast_expression*)call);
1272
1273     if (fun->expression.vtype != TYPE_FUNCTION) {
1274         parseerror(parser, "not a function (%s)", type_name[fun->expression.vtype]);
1275         return false;
1276     }
1277
1278     if (!fun->expression.next) {
1279         parseerror(parser, "could not determine function return type");
1280         return false;
1281     } else {
1282         if (vec_size(fun->expression.params) != paramcount &&
1283             !((fun->expression.flags & AST_FLAG_VARIADIC) &&
1284               vec_size(fun->expression.params) < paramcount))
1285         {
1286             ast_value *fval;
1287             const char *fewmany = (vec_size(fun->expression.params) > paramcount) ? "few" : "many";
1288
1289             fval = (ast_istype(fun, ast_value) ? ((ast_value*)fun) : NULL);
1290             if (opts.standard == COMPILER_GMQCC)
1291             {
1292                 if (fval)
1293                     parseerror(parser, "too %s parameters for call to %s: expected %i, got %i\n"
1294                                " -> `%s` has been declared here: %s:%i",
1295                                fewmany, fval->name, (int)vec_size(fun->expression.params), (int)paramcount,
1296                                fval->name, ast_ctx(fun).file, (int)ast_ctx(fun).line);
1297                 else
1298                     parseerror(parser, "too %s parameters for function call: expected %i, got %i\n"
1299                                " -> it has been declared here: %s:%i",
1300                                fewmany, (int)vec_size(fun->expression.params), (int)paramcount,
1301                                ast_ctx(fun).file, (int)ast_ctx(fun).line);
1302                 return false;
1303             }
1304             else
1305             {
1306                 if (fval)
1307                     return !parsewarning(parser, WARN_TOO_FEW_PARAMETERS,
1308                                          "too %s parameters for call to %s: expected %i, got %i\n"
1309                                          " -> `%s` has been declared here: %s:%i",
1310                                          fewmany, fval->name, (int)vec_size(fun->expression.params), (int)paramcount,
1311                                          fval->name, ast_ctx(fun).file, (int)ast_ctx(fun).line);
1312                 else
1313                     return !parsewarning(parser, WARN_TOO_FEW_PARAMETERS,
1314                                          "too %s parameters for function call: expected %i, got %i\n"
1315                                          " -> it has been declared here: %s:%i",
1316                                          fewmany, (int)vec_size(fun->expression.params), (int)paramcount,
1317                                          ast_ctx(fun).file, (int)ast_ctx(fun).line);
1318             }
1319         }
1320     }
1321
1322     return true;
1323 }
1324
1325 static bool parser_close_paren(parser_t *parser, shunt *sy, bool functions_only)
1326 {
1327     if (!vec_size(sy->ops)) {
1328         parseerror(parser, "unmatched closing paren");
1329         return false;
1330     }
1331     /* this would for bit a + (x) because there are no operators inside (x)
1332     if (sy->ops[vec_size(sy->ops)-1].paren == 1) {
1333         parseerror(parser, "empty parenthesis expression");
1334         return false;
1335     }
1336     */
1337     while (vec_size(sy->ops)) {
1338         if (sy->ops[vec_size(sy->ops)-1].paren == SY_PAREN_FUNC) {
1339             if (!parser_close_call(parser, sy))
1340                 return false;
1341             break;
1342         }
1343         if (sy->ops[vec_size(sy->ops)-1].paren == SY_PAREN_EXPR) {
1344             vec_shrinkby(sy->ops, 1);
1345             return !functions_only;
1346         }
1347         if (sy->ops[vec_size(sy->ops)-1].paren == SY_PAREN_INDEX) {
1348             if (functions_only)
1349                 return false;
1350             /* pop off the parenthesis */
1351             vec_shrinkby(sy->ops, 1);
1352             /* then apply the index operator */
1353             if (!parser_sy_apply_operator(parser, sy))
1354                 return false;
1355             return true;
1356         }
1357         if (sy->ops[vec_size(sy->ops)-1].paren == SY_PAREN_TERNARY) {
1358             if (functions_only)
1359                 return false;
1360             if (vec_last(parser->pot) != POT_TERNARY1) {
1361                 parseerror(parser, "mismatched colon in ternary expression (missing closing paren?)");
1362                 return false;
1363             }
1364             vec_last(parser->pot) = POT_TERNARY2;
1365             /* pop off the parenthesis */
1366             vec_shrinkby(sy->ops, 1);
1367             return true;
1368         }
1369         if (!parser_sy_apply_operator(parser, sy))
1370             return false;
1371     }
1372     return true;
1373 }
1374
1375 static void parser_reclassify_token(parser_t *parser)
1376 {
1377     size_t i;
1378     for (i = 0; i < operator_count; ++i) {
1379         if (!strcmp(parser_tokval(parser), operators[i].op)) {
1380             parser->tok = TOKEN_OPERATOR;
1381             return;
1382         }
1383     }
1384 }
1385
1386 static ast_expression* parse_expression_leave(parser_t *parser, bool stopatcomma)
1387 {
1388     ast_expression *expr = NULL;
1389     shunt sy;
1390     bool wantop = false;
1391     bool gotmemberof = false;
1392
1393     /* count the parens because an if starts with one, so the
1394      * end of a condition is an unmatched closing paren
1395      */
1396     int parens = 0;
1397     int ternaries = 0;
1398
1399     sy.out = NULL;
1400     sy.ops = NULL;
1401
1402     parser->lex->flags.noops = false;
1403
1404     parser_reclassify_token(parser);
1405
1406     while (true)
1407     {
1408         if (gotmemberof)
1409             gotmemberof = false;
1410         else
1411             parser->memberof = 0;
1412
1413         if (OPTS_FLAG(TRANSLATABLE_STRINGS) &&
1414             parser->tok == TOKEN_IDENT && !strcmp(parser_tokval(parser), "_"))
1415         {
1416             /* a translatable string */
1417             ast_value *val;
1418
1419             if (wantop) {
1420                 parseerror(parser, "expected operator or end of statement, got constant");
1421                 goto onerr;
1422             }
1423
1424             parser->lex->flags.noops = true;
1425             if (!parser_next(parser) || parser->tok != '(') {
1426                 parseerror(parser, "use _(\"string\") to create a translatable string constant");
1427                 goto onerr;
1428             }
1429             parser->lex->flags.noops = false;
1430             if (!parser_next(parser) || parser->tok != TOKEN_STRINGCONST) {
1431                 parseerror(parser, "expected a constant string in translatable-string extension");
1432                 goto onerr;
1433             }
1434             val = parser_const_string(parser, parser_tokval(parser), true);
1435             wantop = true;
1436             if (!val)
1437                 return false;
1438             vec_push(sy.out, syexp(parser_ctx(parser), (ast_expression*)val));
1439             DEBUGSHUNTDO(con_out("push string\n"));
1440
1441             if (!parser_next(parser) || parser->tok != ')') {
1442                 parseerror(parser, "expected closing paren after translatable string");
1443                 goto onerr;
1444             }
1445         }
1446         else if (parser->tok == TOKEN_IDENT)
1447         {
1448             ast_expression *var;
1449             if (wantop) {
1450                 parseerror(parser, "expected operator or end of statement");
1451                 goto onerr;
1452             }
1453             wantop = true;
1454             /* variable */
1455             if (opts.standard == COMPILER_GMQCC)
1456             {
1457                 if (parser->memberof == TYPE_ENTITY) {
1458                     /* still get vars first since there could be a fieldpointer */
1459                     var = parser_find_var(parser, parser_tokval(parser));
1460                     if (!var)
1461                         var = parser_find_field(parser, parser_tokval(parser));
1462                 }
1463                 else if (parser->memberof == TYPE_VECTOR)
1464                 {
1465                     parseerror(parser, "TODO: implement effective vector member access");
1466                     goto onerr;
1467                 }
1468                 else if (parser->memberof) {
1469                     parseerror(parser, "namespace for member not found");
1470                     goto onerr;
1471                 }
1472                 else
1473                     var = parser_find_var(parser, parser_tokval(parser));
1474             } else {
1475                 var = parser_find_var(parser, parser_tokval(parser));
1476                 if (!var)
1477                     var = parser_find_field(parser, parser_tokval(parser));
1478             }
1479             if (!var) {
1480                 /* intrinsics */
1481                 if (!strcmp(parser_tokval(parser), "__builtin_debug_typestring")) {
1482                     var = (ast_expression*)intrinsic_debug_typestring;
1483
1484                 }
1485                 else
1486                 {
1487                     parseerror(parser, "unexpected ident: %s", parser_tokval(parser));
1488                     goto onerr;
1489                 }
1490             }
1491             else
1492             {
1493                 if (ast_istype(var, ast_value)) {
1494                     ((ast_value*)var)->uses++;
1495                 }
1496                 else if (ast_istype(var, ast_member)) {
1497                     ast_member *mem = (ast_member*)var;
1498                     if (ast_istype(mem->owner, ast_value))
1499                         ((ast_value*)(mem->owner))->uses++;
1500                 }
1501             }
1502             vec_push(sy.out, syexp(parser_ctx(parser), var));
1503             DEBUGSHUNTDO(con_out("push %s\n", parser_tokval(parser)));
1504         }
1505         else if (parser->tok == TOKEN_FLOATCONST) {
1506             ast_value *val;
1507             if (wantop) {
1508                 parseerror(parser, "expected operator or end of statement, got constant");
1509                 goto onerr;
1510             }
1511             wantop = true;
1512             val = parser_const_float(parser, (parser_token(parser)->constval.f));
1513             if (!val)
1514                 return false;
1515             vec_push(sy.out, syexp(parser_ctx(parser), (ast_expression*)val));
1516             DEBUGSHUNTDO(con_out("push %g\n", parser_token(parser)->constval.f));
1517         }
1518         else if (parser->tok == TOKEN_INTCONST || parser->tok == TOKEN_CHARCONST) {
1519             ast_value *val;
1520             if (wantop) {
1521                 parseerror(parser, "expected operator or end of statement, got constant");
1522                 goto onerr;
1523             }
1524             wantop = true;
1525             val = parser_const_float(parser, (double)(parser_token(parser)->constval.i));
1526             if (!val)
1527                 return false;
1528             vec_push(sy.out, syexp(parser_ctx(parser), (ast_expression*)val));
1529             DEBUGSHUNTDO(con_out("push %i\n", parser_token(parser)->constval.i));
1530         }
1531         else if (parser->tok == TOKEN_STRINGCONST) {
1532             ast_value *val;
1533             if (wantop) {
1534                 parseerror(parser, "expected operator or end of statement, got constant");
1535                 goto onerr;
1536             }
1537             wantop = true;
1538             val = parser_const_string(parser, parser_tokval(parser), false);
1539             if (!val)
1540                 return false;
1541             vec_push(sy.out, syexp(parser_ctx(parser), (ast_expression*)val));
1542             DEBUGSHUNTDO(con_out("push string\n"));
1543         }
1544         else if (parser->tok == TOKEN_VECTORCONST) {
1545             ast_value *val;
1546             if (wantop) {
1547                 parseerror(parser, "expected operator or end of statement, got constant");
1548                 goto onerr;
1549             }
1550             wantop = true;
1551             val = parser_const_vector(parser, parser_token(parser)->constval.v);
1552             if (!val)
1553                 return false;
1554             vec_push(sy.out, syexp(parser_ctx(parser), (ast_expression*)val));
1555             DEBUGSHUNTDO(con_out("push '%g %g %g'\n",
1556                                 parser_token(parser)->constval.v.x,
1557                                 parser_token(parser)->constval.v.y,
1558                                 parser_token(parser)->constval.v.z));
1559         }
1560         else if (parser->tok == '(') {
1561             parseerror(parser, "internal error: '(' should be classified as operator");
1562             goto onerr;
1563         }
1564         else if (parser->tok == '[') {
1565             parseerror(parser, "internal error: '[' should be classified as operator");
1566             goto onerr;
1567         }
1568         else if (parser->tok == ')') {
1569             if (wantop) {
1570                 DEBUGSHUNTDO(con_out("do[op] )\n"));
1571                 --parens;
1572                 if (parens < 0)
1573                     break;
1574                 /* we do expect an operator next */
1575                 /* closing an opening paren */
1576                 if (!parser_close_paren(parser, &sy, false))
1577                     goto onerr;
1578                 if (vec_last(parser->pot) != POT_PAREN) {
1579                     parseerror(parser, "mismatched parentheses (closing paren during ternary expression?)");
1580                     goto onerr;
1581                 }
1582                 vec_pop(parser->pot);
1583             } else {
1584                 DEBUGSHUNTDO(con_out("do[nop] )\n"));
1585                 --parens;
1586                 if (parens < 0)
1587                     break;
1588                 /* allowed for function calls */
1589                 if (!parser_close_paren(parser, &sy, true))
1590                     goto onerr;
1591                 if (vec_last(parser->pot) != POT_PAREN) {
1592                     parseerror(parser, "mismatched parentheses (closing paren during ternary expression?)");
1593                     goto onerr;
1594                 }
1595                 vec_pop(parser->pot);
1596             }
1597             wantop = true;
1598         }
1599         else if (parser->tok == ']') {
1600             if (!wantop)
1601                 parseerror(parser, "operand expected");
1602             --parens;
1603             if (parens < 0)
1604                 break;
1605             if (!parser_close_paren(parser, &sy, false))
1606                 goto onerr;
1607             if (vec_last(parser->pot) != POT_PAREN) {
1608                 parseerror(parser, "mismatched parentheses (closing paren during ternary expression?)");
1609                 goto onerr;
1610             }
1611             vec_pop(parser->pot);
1612             wantop = true;
1613         }
1614         else if (parser->tok == TOKEN_TYPENAME) {
1615             parseerror(parser, "unexpected typename");
1616             goto onerr;
1617         }
1618         else if (parser->tok != TOKEN_OPERATOR) {
1619             if (wantop) {
1620                 parseerror(parser, "expected operator or end of statement");
1621                 goto onerr;
1622             }
1623             break;
1624         }
1625         else
1626         {
1627             /* classify the operator */
1628             const oper_info *op;
1629             const oper_info *olast = NULL;
1630             size_t o;
1631             for (o = 0; o < operator_count; ++o) {
1632                 if ((!(operators[o].flags & OP_PREFIX) == wantop) &&
1633                     /* !(operators[o].flags & OP_SUFFIX) && / * remove this */
1634                     !strcmp(parser_tokval(parser), operators[o].op))
1635                 {
1636                     break;
1637                 }
1638             }
1639             if (o == operator_count) {
1640                 /* no operator found... must be the end of the statement */
1641                 break;
1642             }
1643             /* found an operator */
1644             op = &operators[o];
1645
1646             /* when declaring variables, a comma starts a new variable */
1647             if (op->id == opid1(',') && !parens && stopatcomma) {
1648                 /* fixup the token */
1649                 parser->tok = ',';
1650                 break;
1651             }
1652
1653             /* a colon without a pervious question mark cannot be a ternary */
1654             if (!ternaries && op->id == opid2(':','?')) {
1655                 parser->tok = ':';
1656                 break;
1657             }
1658
1659             if (op->id == opid1(',')) {
1660                 if (vec_size(parser->pot) && vec_last(parser->pot) == POT_TERNARY2) {
1661                     (void)!parsewarning(parser, WARN_TERNARY_PRECEDENCE, "suggesting parenthesis around ternary expression");
1662                 }
1663             }
1664
1665             if (vec_size(sy.ops) && !vec_last(sy.ops).paren)
1666                 olast = &operators[vec_last(sy.ops).etype-1];
1667
1668             while (olast && (
1669                     (op->prec < olast->prec) ||
1670                     (op->assoc == ASSOC_LEFT && op->prec <= olast->prec) ) )
1671             {
1672                 if (!parser_sy_apply_operator(parser, &sy))
1673                     goto onerr;
1674                 if (vec_size(sy.ops) && !vec_last(sy.ops).paren)
1675                     olast = &operators[vec_last(sy.ops).etype-1];
1676                 else
1677                     olast = NULL;
1678             }
1679
1680             if (op->id == opid1('.') && opts.standard == COMPILER_GMQCC) {
1681                 /* for gmqcc standard: open up the namespace of the previous type */
1682                 ast_expression *prevex = vec_last(sy.out).out;
1683                 if (!prevex) {
1684                     parseerror(parser, "unexpected member operator");
1685                     goto onerr;
1686                 }
1687                 if (prevex->expression.vtype == TYPE_ENTITY)
1688                     parser->memberof = TYPE_ENTITY;
1689                 else if (prevex->expression.vtype == TYPE_VECTOR)
1690                     parser->memberof = TYPE_VECTOR;
1691                 else {
1692                     parseerror(parser, "type error: type has no members");
1693                     goto onerr;
1694                 }
1695                 gotmemberof = true;
1696             }
1697
1698             if (op->id == opid1('(')) {
1699                 if (wantop) {
1700                     size_t sycount = vec_size(sy.out);
1701                     DEBUGSHUNTDO(con_out("push [op] (\n"));
1702                     ++parens; vec_push(parser->pot, POT_PAREN);
1703                     /* we expected an operator, this is the function-call operator */
1704                     vec_push(sy.ops, syparen(parser_ctx(parser), SY_PAREN_FUNC, sycount-1));
1705                 } else {
1706                     ++parens; vec_push(parser->pot, POT_PAREN);
1707                     vec_push(sy.ops, syparen(parser_ctx(parser), SY_PAREN_EXPR, 0));
1708                     DEBUGSHUNTDO(con_out("push [nop] (\n"));
1709                 }
1710                 wantop = false;
1711             } else if (op->id == opid1('[')) {
1712                 if (!wantop) {
1713                     parseerror(parser, "unexpected array subscript");
1714                     goto onerr;
1715                 }
1716                 ++parens; vec_push(parser->pot, POT_PAREN);
1717                 /* push both the operator and the paren, this makes life easier */
1718                 vec_push(sy.ops, syop(parser_ctx(parser), op));
1719                 vec_push(sy.ops, syparen(parser_ctx(parser), SY_PAREN_INDEX, 0));
1720                 wantop = false;
1721             } else if (op->id == opid2('?',':')) {
1722                 vec_push(sy.ops, syop(parser_ctx(parser), op));
1723                 vec_push(sy.ops, syparen(parser_ctx(parser), SY_PAREN_TERNARY, 0));
1724                 wantop = false;
1725                 ++ternaries;
1726                 vec_push(parser->pot, POT_TERNARY1);
1727             } else if (op->id == opid2(':','?')) {
1728                 if (!vec_size(parser->pot)) {
1729                     parseerror(parser, "unexpected colon outside ternary expression (missing parenthesis?)");
1730                     goto onerr;
1731                 }
1732                 if (vec_last(parser->pot) != POT_TERNARY1) {
1733                     parseerror(parser, "unexpected colon outside ternary expression (missing parenthesis?)");
1734                     goto onerr;
1735                 }
1736                 if (!parser_close_paren(parser, &sy, false))
1737                     goto onerr;
1738                 vec_push(sy.ops, syop(parser_ctx(parser), op));
1739                 wantop = false;
1740                 --ternaries;
1741             } else {
1742                 DEBUGSHUNTDO(con_out("push operator %s\n", op->op));
1743                 vec_push(sy.ops, syop(parser_ctx(parser), op));
1744                 wantop = !!(op->flags & OP_SUFFIX);
1745             }
1746         }
1747         if (!parser_next(parser)) {
1748             goto onerr;
1749         }
1750         if (parser->tok == ';' ||
1751             (!parens && parser->tok == ']'))
1752         {
1753             break;
1754         }
1755     }
1756
1757     while (vec_size(sy.ops)) {
1758         if (!parser_sy_apply_operator(parser, &sy))
1759             goto onerr;
1760     }
1761
1762     parser->lex->flags.noops = true;
1763     if (!vec_size(sy.out)) {
1764         parseerror(parser, "empty expression");
1765         expr = NULL;
1766     } else
1767         expr = sy.out[0].out;
1768     vec_free(sy.out);
1769     vec_free(sy.ops);
1770     DEBUGSHUNTDO(con_out("shunt done\n"));
1771     if (vec_size(parser->pot)) {
1772         parseerror(parser, "internal error: vec_size(parser->pot) = %lu", (unsigned long)vec_size(parser->pot));
1773         return NULL;
1774     }
1775     vec_free(parser->pot);
1776     return expr;
1777
1778 onerr:
1779     parser->lex->flags.noops = true;
1780     vec_free(sy.out);
1781     vec_free(sy.ops);
1782     return NULL;
1783 }
1784
1785 static ast_expression* parse_expression(parser_t *parser, bool stopatcomma)
1786 {
1787     ast_expression *e = parse_expression_leave(parser, stopatcomma);
1788     if (!e)
1789         return NULL;
1790     if (!parser_next(parser)) {
1791         ast_delete(e);
1792         return NULL;
1793     }
1794     return e;
1795 }
1796
1797 static void parser_enterblock(parser_t *parser)
1798 {
1799     vec_push(parser->variables, util_htnew(PARSER_HT_SIZE));
1800     vec_push(parser->_blocklocals, vec_size(parser->_locals));
1801     vec_push(parser->typedefs, util_htnew(TYPEDEF_HT_SIZE));
1802     vec_push(parser->_blocktypedefs, vec_size(parser->_typedefs));
1803     vec_push(parser->_block_ctx, parser_ctx(parser));
1804 }
1805
1806 static bool parser_leaveblock(parser_t *parser)
1807 {
1808     bool   rv = true;
1809     size_t locals, typedefs;
1810
1811     if (vec_size(parser->variables) <= PARSER_HT_LOCALS) {
1812         parseerror(parser, "internal error: parser_leaveblock with no block");
1813         return false;
1814     }
1815
1816     util_htdel(vec_last(parser->variables));
1817     vec_pop(parser->variables);
1818     if (!vec_size(parser->_blocklocals)) {
1819         parseerror(parser, "internal error: parser_leaveblock with no block (2)");
1820         return false;
1821     }
1822
1823     locals = vec_last(parser->_blocklocals);
1824     vec_pop(parser->_blocklocals);
1825     while (vec_size(parser->_locals) != locals) {
1826         ast_expression *e = vec_last(parser->_locals);
1827         ast_value      *v = (ast_value*)e;
1828         vec_pop(parser->_locals);
1829         if (ast_istype(e, ast_value) && !v->uses) {
1830             if (compile_warning(ast_ctx(v), WARN_UNUSED_VARIABLE, "unused variable: `%s`", v->name)) {
1831                 parser->errors++;
1832                 rv = false;
1833             }
1834         }
1835     }
1836
1837     typedefs = vec_last(parser->_blocktypedefs);
1838     while (vec_size(parser->_typedefs) != typedefs) {
1839         ast_delete(vec_last(parser->_typedefs));
1840         vec_pop(parser->_typedefs);
1841     }
1842     util_htdel(vec_last(parser->typedefs));
1843     vec_pop(parser->typedefs);
1844
1845     vec_pop(parser->_block_ctx);
1846     return rv;
1847 }
1848
1849 static void parser_addlocal(parser_t *parser, const char *name, ast_expression *e)
1850 {
1851     vec_push(parser->_locals, e);
1852     util_htset(vec_last(parser->variables), name, (void*)e);
1853 }
1854
1855 static bool parse_if(parser_t *parser, ast_block *block, ast_expression **out)
1856 {
1857     ast_ifthen *ifthen;
1858     ast_expression *cond, *ontrue, *onfalse = NULL;
1859     bool ifnot = false;
1860
1861     lex_ctx ctx = parser_ctx(parser);
1862
1863     (void)block; /* not touching */
1864
1865     /* skip the 'if', parse an optional 'not' and check for an opening paren */
1866     if (!parser_next(parser)) {
1867         parseerror(parser, "expected condition or 'not'");
1868         return false;
1869     }
1870     if (parser->tok == TOKEN_IDENT && !strcmp(parser_tokval(parser), "not")) {
1871         ifnot = true;
1872         if (!parser_next(parser)) {
1873             parseerror(parser, "expected condition in parenthesis");
1874             return false;
1875         }
1876     }
1877     if (parser->tok != '(') {
1878         parseerror(parser, "expected 'if' condition in parenthesis");
1879         return false;
1880     }
1881     /* parse into the expression */
1882     if (!parser_next(parser)) {
1883         parseerror(parser, "expected 'if' condition after opening paren");
1884         return false;
1885     }
1886     /* parse the condition */
1887     cond = parse_expression_leave(parser, false);
1888     if (!cond)
1889         return false;
1890     /* closing paren */
1891     if (parser->tok != ')') {
1892         parseerror(parser, "expected closing paren after 'if' condition");
1893         ast_delete(cond);
1894         return false;
1895     }
1896     /* parse into the 'then' branch */
1897     if (!parser_next(parser)) {
1898         parseerror(parser, "expected statement for on-true branch of 'if'");
1899         ast_delete(cond);
1900         return false;
1901     }
1902     if (!parse_statement_or_block(parser, &ontrue)) {
1903         ast_delete(cond);
1904         return false;
1905     }
1906     /* check for an else */
1907     if (!strcmp(parser_tokval(parser), "else")) {
1908         /* parse into the 'else' branch */
1909         if (!parser_next(parser)) {
1910             parseerror(parser, "expected on-false branch after 'else'");
1911             ast_delete(ontrue);
1912             ast_delete(cond);
1913             return false;
1914         }
1915         if (!parse_statement_or_block(parser, &onfalse)) {
1916             ast_delete(ontrue);
1917             ast_delete(cond);
1918             return false;
1919         }
1920     }
1921
1922     if (ifnot)
1923         ifthen = ast_ifthen_new(ctx, cond, onfalse, ontrue);
1924     else
1925         ifthen = ast_ifthen_new(ctx, cond, ontrue, onfalse);
1926     *out = (ast_expression*)ifthen;
1927     return true;
1928 }
1929
1930 static bool parse_while(parser_t *parser, ast_block *block, ast_expression **out)
1931 {
1932     ast_loop *aloop;
1933     ast_expression *cond, *ontrue;
1934
1935     lex_ctx ctx = parser_ctx(parser);
1936
1937     (void)block; /* not touching */
1938
1939     /* skip the 'while' and check for opening paren */
1940     if (!parser_next(parser) || parser->tok != '(') {
1941         parseerror(parser, "expected 'while' condition in parenthesis");
1942         return false;
1943     }
1944     /* parse into the expression */
1945     if (!parser_next(parser)) {
1946         parseerror(parser, "expected 'while' condition after opening paren");
1947         return false;
1948     }
1949     /* parse the condition */
1950     cond = parse_expression_leave(parser, false);
1951     if (!cond)
1952         return false;
1953     /* closing paren */
1954     if (parser->tok != ')') {
1955         parseerror(parser, "expected closing paren after 'while' condition");
1956         ast_delete(cond);
1957         return false;
1958     }
1959     /* parse into the 'then' branch */
1960     if (!parser_next(parser)) {
1961         parseerror(parser, "expected while-loop body");
1962         ast_delete(cond);
1963         return false;
1964     }
1965     if (!parse_statement_or_block(parser, &ontrue)) {
1966         ast_delete(cond);
1967         return false;
1968     }
1969
1970     aloop = ast_loop_new(ctx, NULL, cond, NULL, NULL, ontrue);
1971     *out = (ast_expression*)aloop;
1972     return true;
1973 }
1974
1975 static bool parse_dowhile(parser_t *parser, ast_block *block, ast_expression **out)
1976 {
1977     ast_loop *aloop;
1978     ast_expression *cond, *ontrue;
1979
1980     lex_ctx ctx = parser_ctx(parser);
1981
1982     (void)block; /* not touching */
1983
1984     /* skip the 'do' and get the body */
1985     if (!parser_next(parser)) {
1986         parseerror(parser, "expected loop body");
1987         return false;
1988     }
1989     if (!parse_statement_or_block(parser, &ontrue))
1990         return false;
1991
1992     /* expect the "while" */
1993     if (parser->tok != TOKEN_KEYWORD ||
1994         strcmp(parser_tokval(parser), "while"))
1995     {
1996         parseerror(parser, "expected 'while' and condition");
1997         ast_delete(ontrue);
1998         return false;
1999     }
2000
2001     /* skip the 'while' and check for opening paren */
2002     if (!parser_next(parser) || parser->tok != '(') {
2003         parseerror(parser, "expected 'while' condition in parenthesis");
2004         ast_delete(ontrue);
2005         return false;
2006     }
2007     /* parse into the expression */
2008     if (!parser_next(parser)) {
2009         parseerror(parser, "expected 'while' condition after opening paren");
2010         ast_delete(ontrue);
2011         return false;
2012     }
2013     /* parse the condition */
2014     cond = parse_expression_leave(parser, false);
2015     if (!cond)
2016         return false;
2017     /* closing paren */
2018     if (parser->tok != ')') {
2019         parseerror(parser, "expected closing paren after 'while' condition");
2020         ast_delete(ontrue);
2021         ast_delete(cond);
2022         return false;
2023     }
2024     /* parse on */
2025     if (!parser_next(parser) || parser->tok != ';') {
2026         parseerror(parser, "expected semicolon after condition");
2027         ast_delete(ontrue);
2028         ast_delete(cond);
2029         return false;
2030     }
2031
2032     if (!parser_next(parser)) {
2033         parseerror(parser, "parse error");
2034         ast_delete(ontrue);
2035         ast_delete(cond);
2036         return false;
2037     }
2038
2039     aloop = ast_loop_new(ctx, NULL, NULL, cond, NULL, ontrue);
2040     *out = (ast_expression*)aloop;
2041     return true;
2042 }
2043
2044 static bool parse_for(parser_t *parser, ast_block *block, ast_expression **out)
2045 {
2046     ast_loop       *aloop;
2047     ast_expression *initexpr, *cond, *increment, *ontrue;
2048     ast_value      *typevar;
2049     bool   retval = true;
2050
2051     lex_ctx ctx = parser_ctx(parser);
2052
2053     parser_enterblock(parser);
2054
2055     initexpr  = NULL;
2056     cond      = NULL;
2057     increment = NULL;
2058     ontrue    = NULL;
2059
2060     /* skip the 'while' and check for opening paren */
2061     if (!parser_next(parser) || parser->tok != '(') {
2062         parseerror(parser, "expected 'for' expressions in parenthesis");
2063         goto onerr;
2064     }
2065     /* parse into the expression */
2066     if (!parser_next(parser)) {
2067         parseerror(parser, "expected 'for' initializer after opening paren");
2068         goto onerr;
2069     }
2070
2071     typevar = NULL;
2072     if (parser->tok == TOKEN_IDENT)
2073         typevar = parser_find_typedef(parser, parser_tokval(parser), 0);
2074
2075     if (typevar || parser->tok == TOKEN_TYPENAME) {
2076         if (opts.standard != COMPILER_GMQCC) {
2077             if (parsewarning(parser, WARN_EXTENSIONS,
2078                              "current standard does not allow variable declarations in for-loop initializers"))
2079                 goto onerr;
2080         }
2081         if (!parse_variable(parser, block, true, CV_VAR, typevar, false, false))
2082             goto onerr;
2083     }
2084     else if (parser->tok != ';')
2085     {
2086         initexpr = parse_expression_leave(parser, false);
2087         if (!initexpr)
2088             goto onerr;
2089     }
2090
2091     /* move on to condition */
2092     if (parser->tok != ';') {
2093         parseerror(parser, "expected semicolon after for-loop initializer");
2094         goto onerr;
2095     }
2096     if (!parser_next(parser)) {
2097         parseerror(parser, "expected for-loop condition");
2098         goto onerr;
2099     }
2100
2101     /* parse the condition */
2102     if (parser->tok != ';') {
2103         cond = parse_expression_leave(parser, false);
2104         if (!cond)
2105             goto onerr;
2106     }
2107
2108     /* move on to incrementor */
2109     if (parser->tok != ';') {
2110         parseerror(parser, "expected semicolon after for-loop initializer");
2111         goto onerr;
2112     }
2113     if (!parser_next(parser)) {
2114         parseerror(parser, "expected for-loop condition");
2115         goto onerr;
2116     }
2117
2118     /* parse the incrementor */
2119     if (parser->tok != ')') {
2120         increment = parse_expression_leave(parser, false);
2121         if (!increment)
2122             goto onerr;
2123         if (!ast_side_effects(increment)) {
2124             if (genwarning(ast_ctx(increment), WARN_EFFECTLESS_STATEMENT, "statement has no effect"))
2125                 goto onerr;
2126         }
2127     }
2128
2129     /* closing paren */
2130     if (parser->tok != ')') {
2131         parseerror(parser, "expected closing paren after 'for-loop' incrementor");
2132         goto onerr;
2133     }
2134     /* parse into the 'then' branch */
2135     if (!parser_next(parser)) {
2136         parseerror(parser, "expected for-loop body");
2137         goto onerr;
2138     }
2139     if (!parse_statement_or_block(parser, &ontrue))
2140         goto onerr;
2141
2142     aloop = ast_loop_new(ctx, initexpr, cond, NULL, increment, ontrue);
2143     *out = (ast_expression*)aloop;
2144
2145     if (!parser_leaveblock(parser))
2146         retval = false;
2147     return retval;
2148 onerr:
2149     if (initexpr)  ast_delete(initexpr);
2150     if (cond)      ast_delete(cond);
2151     if (increment) ast_delete(increment);
2152     (void)!parser_leaveblock(parser);
2153     return false;
2154 }
2155
2156 static bool parse_return(parser_t *parser, ast_block *block, ast_expression **out)
2157 {
2158     ast_expression *exp = NULL;
2159     ast_return     *ret = NULL;
2160     ast_value      *expected = parser->function->vtype;
2161
2162     lex_ctx ctx = parser_ctx(parser);
2163
2164     (void)block; /* not touching */
2165
2166     if (!parser_next(parser)) {
2167         parseerror(parser, "expected return expression");
2168         return false;
2169     }
2170
2171     if (parser->tok != ';') {
2172         exp = parse_expression(parser, false);
2173         if (!exp)
2174             return false;
2175
2176         if (exp->expression.vtype != expected->expression.next->expression.vtype) {
2177             parseerror(parser, "return with invalid expression");
2178         }
2179
2180         ret = ast_return_new(ctx, exp);
2181         if (!ret) {
2182             ast_delete(exp);
2183             return false;
2184         }
2185     } else {
2186         if (!parser_next(parser))
2187             parseerror(parser, "parse error");
2188         if (expected->expression.next->expression.vtype != TYPE_VOID) {
2189             if (opts.standard != COMPILER_GMQCC)
2190                 (void)!parsewarning(parser, WARN_MISSING_RETURN_VALUES, "return without value");
2191             else
2192                 parseerror(parser, "return without value");
2193         }
2194         ret = ast_return_new(ctx, NULL);
2195     }
2196     *out = (ast_expression*)ret;
2197     return true;
2198 }
2199
2200 static bool parse_break_continue(parser_t *parser, ast_block *block, ast_expression **out, bool is_continue)
2201 {
2202     lex_ctx ctx = parser_ctx(parser);
2203
2204     (void)block; /* not touching */
2205
2206     if (!parser_next(parser) || parser->tok != ';') {
2207         parseerror(parser, "expected semicolon");
2208         return false;
2209     }
2210
2211     if (!parser_next(parser))
2212         parseerror(parser, "parse error");
2213
2214     *out = (ast_expression*)ast_breakcont_new(ctx, is_continue);
2215     return true;
2216 }
2217
2218 /* returns true when it was a variable qualifier, false otherwise!
2219  * on error, cvq is set to CV_WRONG
2220  */
2221 static bool parse_var_qualifiers(parser_t *parser, bool with_local, int *cvq, bool *noref, bool *noreturn)
2222 {
2223     bool had_const = false;
2224     bool had_var   = false;
2225     bool had_noref = false;
2226     bool had_noreturn = false;
2227
2228     for (;;) {
2229         if (!strcmp(parser_tokval(parser), "const"))
2230             had_const = true;
2231         else if (!strcmp(parser_tokval(parser), "var"))
2232             had_var = true;
2233         else if (with_local && !strcmp(parser_tokval(parser), "local"))
2234             had_var = true;
2235         else if (!strcmp(parser_tokval(parser), "noref"))
2236             had_noref = true;
2237         else if (!strcmp(parser_tokval(parser), "noreturn"))
2238             had_noreturn = true;
2239         else if (!had_const && !had_var && !had_noref && !had_noreturn) {
2240             return false;
2241         }
2242         else
2243             break;
2244         if (!parser_next(parser))
2245             goto onerr;
2246     }
2247     if (had_const)
2248         *cvq = CV_CONST;
2249     else if (had_var)
2250         *cvq = CV_VAR;
2251     else
2252         *cvq = CV_NONE;
2253     *noref    = had_noref;
2254     *noreturn = had_noreturn;
2255     return true;
2256 onerr:
2257     parseerror(parser, "parse error after variable qualifier");
2258     *cvq = CV_WRONG;
2259     return true;
2260 }
2261
2262 static bool parse_switch(parser_t *parser, ast_block *block, ast_expression **out)
2263 {
2264     ast_expression *operand;
2265     ast_value      *opval;
2266     ast_value      *typevar;
2267     ast_switch     *switchnode;
2268     ast_switch_case swcase;
2269
2270     int  cvq;
2271     bool noref, noreturn;
2272
2273     lex_ctx ctx = parser_ctx(parser);
2274
2275     (void)block; /* not touching */
2276     (void)opval;
2277
2278     /* parse over the opening paren */
2279     if (!parser_next(parser) || parser->tok != '(') {
2280         parseerror(parser, "expected switch operand in parenthesis");
2281         return false;
2282     }
2283
2284     /* parse into the expression */
2285     if (!parser_next(parser)) {
2286         parseerror(parser, "expected switch operand");
2287         return false;
2288     }
2289     /* parse the operand */
2290     operand = parse_expression_leave(parser, false);
2291     if (!operand)
2292         return false;
2293
2294     switchnode = ast_switch_new(ctx, operand);
2295
2296     /* closing paren */
2297     if (parser->tok != ')') {
2298         ast_delete(switchnode);
2299         parseerror(parser, "expected closing paren after 'switch' operand");
2300         return false;
2301     }
2302
2303     /* parse over the opening paren */
2304     if (!parser_next(parser) || parser->tok != '{') {
2305         ast_delete(switchnode);
2306         parseerror(parser, "expected list of cases");
2307         return false;
2308     }
2309
2310     if (!parser_next(parser)) {
2311         ast_delete(switchnode);
2312         parseerror(parser, "expected 'case' or 'default'");
2313         return false;
2314     }
2315
2316     /* new block; allow some variables to be declared here */
2317     parser_enterblock(parser);
2318     while (true) {
2319         typevar = NULL;
2320         if (parser->tok == TOKEN_IDENT)
2321             typevar = parser_find_typedef(parser, parser_tokval(parser), 0);
2322         if (typevar || parser->tok == TOKEN_TYPENAME) {
2323             if (!parse_variable(parser, block, false, CV_NONE, typevar, false, false)) {
2324                 ast_delete(switchnode);
2325                 return false;
2326             }
2327             continue;
2328         }
2329         if (parse_var_qualifiers(parser, true, &cvq, &noref, &noreturn))
2330         {
2331             if (cvq == CV_WRONG) {
2332                 ast_delete(switchnode);
2333                 return false;
2334             }
2335             if (!parse_variable(parser, block, false, cvq, NULL, noref, noreturn)) {
2336                 ast_delete(switchnode);
2337                 return false;
2338             }
2339             continue;
2340         }
2341         break;
2342     }
2343
2344     /* case list! */
2345     while (parser->tok != '}') {
2346         ast_block *caseblock;
2347
2348         if (parser->tok != TOKEN_KEYWORD) {
2349             ast_delete(switchnode);
2350             parseerror(parser, "expected 'case' or 'default'");
2351             return false;
2352         }
2353         if (!strcmp(parser_tokval(parser), "case")) {
2354             if (!parser_next(parser)) {
2355                 ast_delete(switchnode);
2356                 parseerror(parser, "expected expression for case");
2357                 return false;
2358             }
2359             swcase.value = parse_expression_leave(parser, false);
2360             if (!swcase.value) {
2361                 ast_delete(switchnode);
2362                 parseerror(parser, "expected expression for case");
2363                 return false;
2364             }
2365             if (!OPTS_FLAG(RELAXED_SWITCH)) {
2366                 if (!ast_istype(swcase.value, ast_value)) { /* || ((ast_value*)swcase.value)->cvq != CV_CONST) { */
2367                     parseerror(parser, "case on non-constant values need to be explicitly enabled via -frelaxed-switch");
2368                     ast_unref(operand);
2369                     return false;
2370                 }
2371             }
2372         }
2373         else if (!strcmp(parser_tokval(parser), "default")) {
2374             swcase.value = NULL;
2375             if (!parser_next(parser)) {
2376                 ast_delete(switchnode);
2377                 parseerror(parser, "expected colon");
2378                 return false;
2379             }
2380         }
2381
2382         /* Now the colon and body */
2383         if (parser->tok != ':') {
2384             if (swcase.value) ast_unref(swcase.value);
2385             ast_delete(switchnode);
2386             parseerror(parser, "expected colon");
2387             return false;
2388         }
2389
2390         if (!parser_next(parser)) {
2391             if (swcase.value) ast_unref(swcase.value);
2392             ast_delete(switchnode);
2393             parseerror(parser, "expected statements or case");
2394             return false;
2395         }
2396         caseblock = ast_block_new(parser_ctx(parser));
2397         if (!caseblock) {
2398             if (swcase.value) ast_unref(swcase.value);
2399             ast_delete(switchnode);
2400             return false;
2401         }
2402         swcase.code = (ast_expression*)caseblock;
2403         vec_push(switchnode->cases, swcase);
2404         while (true) {
2405             ast_expression *expr;
2406             if (parser->tok == '}')
2407                 break;
2408             if (parser->tok == TOKEN_KEYWORD) {
2409                 if (!strcmp(parser_tokval(parser), "case") ||
2410                     !strcmp(parser_tokval(parser), "default"))
2411                 {
2412                     break;
2413                 }
2414             }
2415             if (!parse_statement(parser, caseblock, &expr, true)) {
2416                 ast_delete(switchnode);
2417                 return false;
2418             }
2419             if (!expr)
2420                 continue;
2421             if (!ast_block_add_expr(caseblock, expr)) {
2422                 ast_delete(switchnode);
2423                 return false;
2424             }
2425         }
2426     }
2427
2428     parser_leaveblock(parser);
2429
2430     /* closing paren */
2431     if (parser->tok != '}') {
2432         ast_delete(switchnode);
2433         parseerror(parser, "expected closing paren of case list");
2434         return false;
2435     }
2436     if (!parser_next(parser)) {
2437         ast_delete(switchnode);
2438         parseerror(parser, "parse error after switch");
2439         return false;
2440     }
2441     *out = (ast_expression*)switchnode;
2442     return true;
2443 }
2444
2445 static bool parse_goto(parser_t *parser, ast_expression **out)
2446 {
2447     size_t    i;
2448     ast_goto *gt;
2449
2450     if (!parser_next(parser) || parser->tok != TOKEN_IDENT) {
2451         parseerror(parser, "expected label name after `goto`");
2452         return false;
2453     }
2454
2455     gt = ast_goto_new(parser_ctx(parser), parser_tokval(parser));
2456
2457     for (i = 0; i < vec_size(parser->labels); ++i) {
2458         if (!strcmp(parser->labels[i]->name, parser_tokval(parser))) {
2459             ast_goto_set_label(gt, parser->labels[i]);
2460             break;
2461         }
2462     }
2463     if (i == vec_size(parser->labels))
2464         vec_push(parser->gotos, gt);
2465
2466     if (!parser_next(parser) || parser->tok != ';') {
2467         parseerror(parser, "semicolon expected after goto label");
2468         return false;
2469     }
2470     if (!parser_next(parser)) {
2471         parseerror(parser, "parse error after goto");
2472         return false;
2473     }
2474
2475     *out = (ast_expression*)gt;
2476     return true;
2477 }
2478
2479 static bool parse_skipwhite(parser_t *parser)
2480 {
2481     do {
2482         if (!parser_next(parser))
2483             return false;
2484     } while (parser->tok == TOKEN_WHITE && parser->tok < TOKEN_ERROR);
2485     return parser->tok < TOKEN_ERROR;
2486 }
2487
2488 static bool parse_eol(parser_t *parser)
2489 {
2490     if (!parse_skipwhite(parser))
2491         return false;
2492     return parser->tok == TOKEN_EOL;
2493 }
2494
2495 static bool parse_pragma_do(parser_t *parser)
2496 {
2497     if (!parser_next(parser) ||
2498         parser->tok != TOKEN_IDENT ||
2499         strcmp(parser_tokval(parser), "pragma"))
2500     {
2501         parseerror(parser, "expected `pragma` keyword after `#`, got `%s`", parser_tokval(parser));
2502         return false;
2503     }
2504     if (!parse_skipwhite(parser) || parser->tok != TOKEN_IDENT) {
2505         parseerror(parser, "expected pragma, got `%s`", parser_tokval(parser));
2506         return false;
2507     }
2508
2509     if (!strcmp(parser_tokval(parser), "noref")) {
2510         if (!parse_skipwhite(parser) || parser->tok != TOKEN_INTCONST) {
2511             parseerror(parser, "`noref` pragma requires an argument: 0 or 1");
2512             return false;
2513         }
2514         parser->noref = !!parser_token(parser)->constval.i;
2515         if (!parse_eol(parser)) {
2516             parseerror(parser, "parse error after `noref` pragma");
2517             return false;
2518         }
2519     }
2520     else
2521     {
2522         (void)!parsewarning(parser, WARN_UNKNOWN_PRAGMAS, "ignoring #pragma %s", parser_tokval(parser));
2523         return false;
2524     }
2525
2526     return true;
2527 }
2528
2529 static bool parse_pragma(parser_t *parser)
2530 {
2531     bool rv;
2532     parser->lex->flags.preprocessing = true;
2533     parser->lex->flags.mergelines = true;
2534     rv = parse_pragma_do(parser);
2535     if (parser->tok != TOKEN_EOL) {
2536         parseerror(parser, "junk after pragma");
2537         rv = false;
2538     }
2539     parser->lex->flags.preprocessing = false;
2540     parser->lex->flags.mergelines = false;
2541     if (!parser_next(parser)) {
2542         parseerror(parser, "parse error after pragma");
2543         rv = false;
2544     }
2545     return rv;
2546 }
2547
2548 static bool parse_statement(parser_t *parser, ast_block *block, ast_expression **out, bool allow_cases)
2549 {
2550     bool       noref, noreturn;
2551     int        cvq = CV_NONE;
2552     ast_value *typevar = NULL;
2553
2554     *out = NULL;
2555
2556     if (parser->tok == TOKEN_IDENT)
2557         typevar = parser_find_typedef(parser, parser_tokval(parser), 0);
2558
2559     if (typevar || parser->tok == TOKEN_TYPENAME || parser->tok == '.')
2560     {
2561         /* local variable */
2562         if (!block) {
2563             parseerror(parser, "cannot declare a variable from here");
2564             return false;
2565         }
2566         if (opts.standard == COMPILER_QCC) {
2567             if (parsewarning(parser, WARN_EXTENSIONS, "missing 'local' keyword when declaring a local variable"))
2568                 return false;
2569         }
2570         if (!parse_variable(parser, block, false, CV_NONE, typevar, false, false))
2571             return false;
2572         return true;
2573     }
2574     else if (parse_var_qualifiers(parser, !!block, &cvq, &noref, &noreturn))
2575     {
2576         if (cvq == CV_WRONG)
2577             return false;
2578         return parse_variable(parser, block, true, cvq, NULL, noref, noreturn);
2579     }
2580     else if (parser->tok == TOKEN_KEYWORD)
2581     {
2582         if (!strcmp(parser_tokval(parser), "__builtin_debug_printtype"))
2583         {
2584             char ty[1024];
2585             ast_value *tdef;
2586
2587             if (!parser_next(parser)) {
2588                 parseerror(parser, "parse error after __builtin_debug_printtype");
2589                 return false;
2590             }
2591
2592             if (parser->tok == TOKEN_IDENT && (tdef = parser_find_typedef(parser, parser_tokval(parser), 0)))
2593             {
2594                 ast_type_to_string((ast_expression*)tdef, ty, sizeof(ty));
2595                 con_out("__builtin_debug_printtype: `%s`=`%s`\n", tdef->name, ty);
2596                 if (!parser_next(parser)) {
2597                     parseerror(parser, "parse error after __builtin_debug_printtype typename argument");
2598                     return false;
2599                 }
2600             }
2601             else
2602             {
2603                 if (!parse_statement(parser, block, out, allow_cases))
2604                     return false;
2605                 if (!*out)
2606                     con_out("__builtin_debug_printtype: got no output node\n");
2607                 else
2608                 {
2609                     ast_type_to_string(*out, ty, sizeof(ty));
2610                     con_out("__builtin_debug_printtype: `%s`\n", ty);
2611                 }
2612             }
2613             return true;
2614         }
2615         else if (!strcmp(parser_tokval(parser), "return"))
2616         {
2617             return parse_return(parser, block, out);
2618         }
2619         else if (!strcmp(parser_tokval(parser), "if"))
2620         {
2621             return parse_if(parser, block, out);
2622         }
2623         else if (!strcmp(parser_tokval(parser), "while"))
2624         {
2625             return parse_while(parser, block, out);
2626         }
2627         else if (!strcmp(parser_tokval(parser), "do"))
2628         {
2629             return parse_dowhile(parser, block, out);
2630         }
2631         else if (!strcmp(parser_tokval(parser), "for"))
2632         {
2633             if (opts.standard == COMPILER_QCC) {
2634                 if (parsewarning(parser, WARN_EXTENSIONS, "for loops are not recognized in the original Quake C standard, to enable try an alternate standard --std=?"))
2635                     return false;
2636             }
2637             return parse_for(parser, block, out);
2638         }
2639         else if (!strcmp(parser_tokval(parser), "break"))
2640         {
2641             return parse_break_continue(parser, block, out, false);
2642         }
2643         else if (!strcmp(parser_tokval(parser), "continue"))
2644         {
2645             return parse_break_continue(parser, block, out, true);
2646         }
2647         else if (!strcmp(parser_tokval(parser), "switch"))
2648         {
2649             return parse_switch(parser, block, out);
2650         }
2651         else if (!strcmp(parser_tokval(parser), "case") ||
2652                  !strcmp(parser_tokval(parser), "default"))
2653         {
2654             if (!allow_cases) {
2655                 parseerror(parser, "unexpected 'case' label");
2656                 return false;
2657             }
2658             return true;
2659         }
2660         else if (!strcmp(parser_tokval(parser), "goto"))
2661         {
2662             return parse_goto(parser, out);
2663         }
2664         else if (!strcmp(parser_tokval(parser), "typedef"))
2665         {
2666             if (!parser_next(parser)) {
2667                 parseerror(parser, "expected type definition after 'typedef'");
2668                 return false;
2669             }
2670             return parse_typedef(parser);
2671         }
2672         parseerror(parser, "Unexpected keyword");
2673         return false;
2674     }
2675     else if (parser->tok == '{')
2676     {
2677         ast_block *inner;
2678         inner = parse_block(parser);
2679         if (!inner)
2680             return false;
2681         *out = (ast_expression*)inner;
2682         return true;
2683     }
2684     else if (parser->tok == ':')
2685     {
2686         size_t i;
2687         ast_label *label;
2688         if (!parser_next(parser)) {
2689             parseerror(parser, "expected label name");
2690             return false;
2691         }
2692         if (parser->tok != TOKEN_IDENT) {
2693             parseerror(parser, "label must be an identifier");
2694             return false;
2695         }
2696         label = ast_label_new(parser_ctx(parser), parser_tokval(parser));
2697         if (!label)
2698             return false;
2699         vec_push(parser->labels, label);
2700         *out = (ast_expression*)label;
2701         if (!parser_next(parser)) {
2702             parseerror(parser, "parse error after label");
2703             return false;
2704         }
2705         for (i = 0; i < vec_size(parser->gotos); ++i) {
2706             if (!strcmp(parser->gotos[i]->name, label->name)) {
2707                 ast_goto_set_label(parser->gotos[i], label);
2708                 vec_remove(parser->gotos, i, 1);
2709                 --i;
2710             }
2711         }
2712         return true;
2713     }
2714     else if (parser->tok == ';')
2715     {
2716         if (!parser_next(parser)) {
2717             parseerror(parser, "parse error after empty statement");
2718             return false;
2719         }
2720         return true;
2721     }
2722     else
2723     {
2724         ast_expression *exp = parse_expression(parser, false);
2725         if (!exp)
2726             return false;
2727         *out = exp;
2728         if (!ast_side_effects(exp)) {
2729             if (genwarning(ast_ctx(exp), WARN_EFFECTLESS_STATEMENT, "statement has no effect"))
2730                 return false;
2731         }
2732         return true;
2733     }
2734 }
2735
2736 static bool parse_block_into(parser_t *parser, ast_block *block)
2737 {
2738     bool   retval = true;
2739
2740     parser_enterblock(parser);
2741
2742     if (!parser_next(parser)) { /* skip the '{' */
2743         parseerror(parser, "expected function body");
2744         goto cleanup;
2745     }
2746
2747     while (parser->tok != TOKEN_EOF && parser->tok < TOKEN_ERROR)
2748     {
2749         ast_expression *expr = NULL;
2750         if (parser->tok == '}')
2751             break;
2752
2753         if (!parse_statement(parser, block, &expr, false)) {
2754             /* parseerror(parser, "parse error"); */
2755             block = NULL;
2756             goto cleanup;
2757         }
2758         if (!expr)
2759             continue;
2760         if (!ast_block_add_expr(block, expr)) {
2761             ast_delete(block);
2762             block = NULL;
2763             goto cleanup;
2764         }
2765     }
2766
2767     if (parser->tok != '}') {
2768         block = NULL;
2769     } else {
2770         (void)parser_next(parser);
2771     }
2772
2773 cleanup:
2774     if (!parser_leaveblock(parser))
2775         retval = false;
2776     return retval && !!block;
2777 }
2778
2779 static ast_block* parse_block(parser_t *parser)
2780 {
2781     ast_block *block;
2782     block = ast_block_new(parser_ctx(parser));
2783     if (!block)
2784         return NULL;
2785     if (!parse_block_into(parser, block)) {
2786         ast_block_delete(block);
2787         return NULL;
2788     }
2789     return block;
2790 }
2791
2792 static bool parse_statement_or_block(parser_t *parser, ast_expression **out)
2793 {
2794     if (parser->tok == '{') {
2795         *out = (ast_expression*)parse_block(parser);
2796         return !!*out;
2797     }
2798     return parse_statement(parser, NULL, out, false);
2799 }
2800
2801 static bool create_vector_members(ast_value *var, ast_member **me)
2802 {
2803     size_t i;
2804     size_t len = strlen(var->name);
2805
2806     for (i = 0; i < 3; ++i) {
2807         char *name = mem_a(len+3);
2808         memcpy(name, var->name, len);
2809         name[len+0] = '_';
2810         name[len+1] = 'x'+i;
2811         name[len+2] = 0;
2812         me[i] = ast_member_new(ast_ctx(var), (ast_expression*)var, i, name);
2813         mem_d(name);
2814         if (!me[i])
2815             break;
2816     }
2817     if (i == 3)
2818         return true;
2819
2820     /* unroll */
2821     do { ast_member_delete(me[--i]); } while(i);
2822     return false;
2823 }
2824
2825 static bool parse_function_body(parser_t *parser, ast_value *var)
2826 {
2827     ast_block      *block = NULL;
2828     ast_function   *func;
2829     ast_function   *old;
2830     size_t          parami;
2831
2832     ast_expression *framenum  = NULL;
2833     ast_expression *nextthink = NULL;
2834     /* None of the following have to be deleted */
2835     ast_expression *fld_think = NULL, *fld_nextthink = NULL, *fld_frame = NULL;
2836     ast_expression *gbl_time = NULL, *gbl_self = NULL;
2837     bool            has_frame_think;
2838
2839     bool retval = true;
2840
2841     has_frame_think = false;
2842     old = parser->function;
2843
2844     if (vec_size(parser->gotos) || vec_size(parser->labels)) {
2845         parseerror(parser, "gotos/labels leaking");
2846         return false;
2847     }
2848
2849     if (var->expression.flags & AST_FLAG_VARIADIC) {
2850         if (parsewarning(parser, WARN_VARIADIC_FUNCTION,
2851                          "variadic function with implementation will not be able to access additional parameters"))
2852         {
2853             return false;
2854         }
2855     }
2856
2857     if (parser->tok == '[') {
2858         /* got a frame definition: [ framenum, nextthink ]
2859          * this translates to:
2860          * self.frame = framenum;
2861          * self.nextthink = time + 0.1;
2862          * self.think = nextthink;
2863          */
2864         nextthink = NULL;
2865
2866         fld_think     = parser_find_field(parser, "think");
2867         fld_nextthink = parser_find_field(parser, "nextthink");
2868         fld_frame     = parser_find_field(parser, "frame");
2869         if (!fld_think || !fld_nextthink || !fld_frame) {
2870             parseerror(parser, "cannot use [frame,think] notation without the required fields");
2871             parseerror(parser, "please declare the following entityfields: `frame`, `think`, `nextthink`");
2872             return false;
2873         }
2874         gbl_time      = parser_find_global(parser, "time");
2875         gbl_self      = parser_find_global(parser, "self");
2876         if (!gbl_time || !gbl_self) {
2877             parseerror(parser, "cannot use [frame,think] notation without the required globals");
2878             parseerror(parser, "please declare the following globals: `time`, `self`");
2879             return false;
2880         }
2881
2882         if (!parser_next(parser))
2883             return false;
2884
2885         framenum = parse_expression_leave(parser, true);
2886         if (!framenum) {
2887             parseerror(parser, "expected a framenumber constant in[frame,think] notation");
2888             return false;
2889         }
2890         if (!ast_istype(framenum, ast_value) || !( (ast_value*)framenum )->hasvalue) {
2891             ast_unref(framenum);
2892             parseerror(parser, "framenumber in [frame,think] notation must be a constant");
2893             return false;
2894         }
2895
2896         if (parser->tok != ',') {
2897             ast_unref(framenum);
2898             parseerror(parser, "expected comma after frame number in [frame,think] notation");
2899             parseerror(parser, "Got a %i\n", parser->tok);
2900             return false;
2901         }
2902
2903         if (!parser_next(parser)) {
2904             ast_unref(framenum);
2905             return false;
2906         }
2907
2908         if (parser->tok == TOKEN_IDENT && !parser_find_var(parser, parser_tokval(parser)))
2909         {
2910             /* qc allows the use of not-yet-declared functions here
2911              * - this automatically creates a prototype */
2912             ast_value      *thinkfunc;
2913             ast_expression *functype = fld_think->expression.next;
2914
2915             thinkfunc = ast_value_new(parser_ctx(parser), parser_tokval(parser), functype->expression.vtype);
2916             if (!thinkfunc || !ast_type_adopt(thinkfunc, functype)) {
2917                 ast_unref(framenum);
2918                 parseerror(parser, "failed to create implicit prototype for `%s`", parser_tokval(parser));
2919                 return false;
2920             }
2921
2922             if (!parser_next(parser)) {
2923                 ast_unref(framenum);
2924                 ast_delete(thinkfunc);
2925                 return false;
2926             }
2927
2928             vec_push(parser->globals, (ast_expression*)thinkfunc);
2929             util_htset(parser->htglobals, thinkfunc->name, thinkfunc);
2930             nextthink = (ast_expression*)thinkfunc;
2931
2932         } else {
2933             nextthink = parse_expression_leave(parser, true);
2934             if (!nextthink) {
2935                 ast_unref(framenum);
2936                 parseerror(parser, "expected a think-function in [frame,think] notation");
2937                 return false;
2938             }
2939         }
2940
2941         if (!ast_istype(nextthink, ast_value)) {
2942             parseerror(parser, "think-function in [frame,think] notation must be a constant");
2943             retval = false;
2944         }
2945
2946         if (retval && parser->tok != ']') {
2947             parseerror(parser, "expected closing `]` for [frame,think] notation");
2948             retval = false;
2949         }
2950
2951         if (retval && !parser_next(parser)) {
2952             retval = false;
2953         }
2954
2955         if (retval && parser->tok != '{') {
2956             parseerror(parser, "a function body has to be declared after a [frame,think] declaration");
2957             retval = false;
2958         }
2959
2960         if (!retval) {
2961             ast_unref(nextthink);
2962             ast_unref(framenum);
2963             return false;
2964         }
2965
2966         has_frame_think = true;
2967     }
2968
2969     block = ast_block_new(parser_ctx(parser));
2970     if (!block) {
2971         parseerror(parser, "failed to allocate block");
2972         if (has_frame_think) {
2973             ast_unref(nextthink);
2974             ast_unref(framenum);
2975         }
2976         return false;
2977     }
2978
2979     if (has_frame_think) {
2980         lex_ctx ctx;
2981         ast_expression *self_frame;
2982         ast_expression *self_nextthink;
2983         ast_expression *self_think;
2984         ast_expression *time_plus_1;
2985         ast_store *store_frame;
2986         ast_store *store_nextthink;
2987         ast_store *store_think;
2988
2989         ctx = parser_ctx(parser);
2990         self_frame     = (ast_expression*)ast_entfield_new(ctx, gbl_self, fld_frame);
2991         self_nextthink = (ast_expression*)ast_entfield_new(ctx, gbl_self, fld_nextthink);
2992         self_think     = (ast_expression*)ast_entfield_new(ctx, gbl_self, fld_think);
2993
2994         time_plus_1    = (ast_expression*)ast_binary_new(ctx, INSTR_ADD_F,
2995                          gbl_time, (ast_expression*)parser_const_float(parser, 0.1));
2996
2997         if (!self_frame || !self_nextthink || !self_think || !time_plus_1) {
2998             if (self_frame)     ast_delete(self_frame);
2999             if (self_nextthink) ast_delete(self_nextthink);
3000             if (self_think)     ast_delete(self_think);
3001             if (time_plus_1)    ast_delete(time_plus_1);
3002             retval = false;
3003         }
3004
3005         if (retval)
3006         {
3007             store_frame     = ast_store_new(ctx, INSTR_STOREP_F,   self_frame,     framenum);
3008             store_nextthink = ast_store_new(ctx, INSTR_STOREP_F,   self_nextthink, time_plus_1);
3009             store_think     = ast_store_new(ctx, INSTR_STOREP_FNC, self_think,     nextthink);
3010
3011             if (!store_frame) {
3012                 ast_delete(self_frame);
3013                 retval = false;
3014             }
3015             if (!store_nextthink) {
3016                 ast_delete(self_nextthink);
3017                 retval = false;
3018             }
3019             if (!store_think) {
3020                 ast_delete(self_think);
3021                 retval = false;
3022             }
3023             if (!retval) {
3024                 if (store_frame)     ast_delete(store_frame);
3025                 if (store_nextthink) ast_delete(store_nextthink);
3026                 if (store_think)     ast_delete(store_think);
3027                 retval = false;
3028             }
3029             if (!ast_block_add_expr(block, (ast_expression*)store_frame) ||
3030                 !ast_block_add_expr(block, (ast_expression*)store_nextthink) ||
3031                 !ast_block_add_expr(block, (ast_expression*)store_think))
3032             {
3033                 retval = false;
3034             }
3035         }
3036
3037         if (!retval) {
3038             parseerror(parser, "failed to generate code for [frame,think]");
3039             ast_unref(nextthink);
3040             ast_unref(framenum);
3041             ast_delete(block);
3042             return false;
3043         }
3044     }
3045
3046     parser_enterblock(parser);
3047
3048     for (parami = 0; parami < vec_size(var->expression.params); ++parami) {
3049         size_t     e;
3050         ast_value *param = var->expression.params[parami];
3051         ast_member *me[3];
3052
3053         if (param->expression.vtype != TYPE_VECTOR &&
3054             (param->expression.vtype != TYPE_FIELD ||
3055              param->expression.next->expression.vtype != TYPE_VECTOR))
3056         {
3057             continue;
3058         }
3059
3060         if (!create_vector_members(param, me)) {
3061             ast_block_delete(block);
3062             return false;
3063         }
3064
3065         for (e = 0; e < 3; ++e) {
3066             parser_addlocal(parser, me[e]->name, (ast_expression*)me[e]);
3067             ast_block_collect(block, (ast_expression*)me[e]);
3068         }
3069     }
3070
3071     func = ast_function_new(ast_ctx(var), var->name, var);
3072     if (!func) {
3073         parseerror(parser, "failed to allocate function for `%s`", var->name);
3074         ast_block_delete(block);
3075         goto enderr;
3076     }
3077     vec_push(parser->functions, func);
3078
3079     parser->function = func;
3080     if (!parse_block_into(parser, block)) {
3081         ast_block_delete(block);
3082         goto enderrfn;
3083     }
3084
3085     vec_push(func->blocks, block);
3086
3087     parser->function = old;
3088     if (!parser_leaveblock(parser))
3089         retval = false;
3090     if (vec_size(parser->variables) != PARSER_HT_LOCALS) {
3091         parseerror(parser, "internal error: local scopes left");
3092         retval = false;
3093     }
3094
3095     if (parser->tok == ';')
3096         return parser_next(parser);
3097     else if (opts.standard == COMPILER_QCC)
3098         parseerror(parser, "missing semicolon after function body (mandatory with -std=qcc)");
3099     return retval;
3100
3101 enderrfn:
3102     vec_pop(parser->functions);
3103     ast_function_delete(func);
3104     var->constval.vfunc = NULL;
3105
3106 enderr:
3107     (void)!parser_leaveblock(parser);
3108     parser->function = old;
3109     return false;
3110 }
3111
3112 static ast_expression *array_accessor_split(
3113     parser_t  *parser,
3114     ast_value *array,
3115     ast_value *index,
3116     size_t     middle,
3117     ast_expression *left,
3118     ast_expression *right
3119     )
3120 {
3121     ast_ifthen *ifthen;
3122     ast_binary *cmp;
3123
3124     lex_ctx ctx = ast_ctx(array);
3125
3126     if (!left || !right) {
3127         if (left)  ast_delete(left);
3128         if (right) ast_delete(right);
3129         return NULL;
3130     }
3131
3132     cmp = ast_binary_new(ctx, INSTR_LT,
3133                          (ast_expression*)index,
3134                          (ast_expression*)parser_const_float(parser, middle));
3135     if (!cmp) {
3136         ast_delete(left);
3137         ast_delete(right);
3138         parseerror(parser, "internal error: failed to create comparison for array setter");
3139         return NULL;
3140     }
3141
3142     ifthen = ast_ifthen_new(ctx, (ast_expression*)cmp, left, right);
3143     if (!ifthen) {
3144         ast_delete(cmp); /* will delete left and right */
3145         parseerror(parser, "internal error: failed to create conditional jump for array setter");
3146         return NULL;
3147     }
3148
3149     return (ast_expression*)ifthen;
3150 }
3151
3152 static ast_expression *array_setter_node(parser_t *parser, ast_value *array, ast_value *index, ast_value *value, size_t from, size_t afterend)
3153 {
3154     lex_ctx ctx = ast_ctx(array);
3155
3156     if (from+1 == afterend) {
3157         /* set this value */
3158         ast_block       *block;
3159         ast_return      *ret;
3160         ast_array_index *subscript;
3161         ast_store       *st;
3162         int assignop = type_store_instr[value->expression.vtype];
3163
3164         if (value->expression.vtype == TYPE_FIELD && value->expression.next->expression.vtype == TYPE_VECTOR)
3165             assignop = INSTR_STORE_V;
3166
3167         subscript = ast_array_index_new(ctx, (ast_expression*)array, (ast_expression*)parser_const_float(parser, from));
3168         if (!subscript)
3169             return NULL;
3170
3171         st = ast_store_new(ctx, assignop, (ast_expression*)subscript, (ast_expression*)value);
3172         if (!st) {
3173             ast_delete(subscript);
3174             return NULL;
3175         }
3176
3177         block = ast_block_new(ctx);
3178         if (!block) {
3179             ast_delete(st);
3180             return NULL;
3181         }
3182
3183         if (!ast_block_add_expr(block, (ast_expression*)st)) {
3184             ast_delete(block);
3185             return NULL;
3186         }
3187
3188         ret = ast_return_new(ctx, NULL);
3189         if (!ret) {
3190             ast_delete(block);
3191             return NULL;
3192         }
3193
3194         if (!ast_block_add_expr(block, (ast_expression*)ret)) {
3195             ast_delete(block);
3196             return NULL;
3197         }
3198
3199         return (ast_expression*)block;
3200     } else {
3201         ast_expression *left, *right;
3202         size_t diff = afterend - from;
3203         size_t middle = from + diff/2;
3204         left  = array_setter_node(parser, array, index, value, from, middle);
3205         right = array_setter_node(parser, array, index, value, middle, afterend);
3206         return array_accessor_split(parser, array, index, middle, left, right);
3207     }
3208 }
3209
3210 static ast_expression *array_field_setter_node(
3211     parser_t  *parser,
3212     ast_value *array,
3213     ast_value *entity,
3214     ast_value *index,
3215     ast_value *value,
3216     size_t     from,
3217     size_t     afterend)
3218 {
3219     lex_ctx ctx = ast_ctx(array);
3220
3221     if (from+1 == afterend) {
3222         /* set this value */
3223         ast_block       *block;
3224         ast_return      *ret;
3225         ast_entfield    *entfield;
3226         ast_array_index *subscript;
3227         ast_store       *st;
3228         int assignop = type_storep_instr[value->expression.vtype];
3229
3230         if (value->expression.vtype == TYPE_FIELD && value->expression.next->expression.vtype == TYPE_VECTOR)
3231             assignop = INSTR_STOREP_V;
3232
3233         subscript = ast_array_index_new(ctx, (ast_expression*)array, (ast_expression*)parser_const_float(parser, from));
3234         if (!subscript)
3235             return NULL;
3236
3237         entfield = ast_entfield_new_force(ctx,
3238                                           (ast_expression*)entity,
3239                                           (ast_expression*)subscript,
3240                                           (ast_expression*)subscript);
3241         if (!entfield) {
3242             ast_delete(subscript);
3243             return NULL;
3244         }
3245
3246         st = ast_store_new(ctx, assignop, (ast_expression*)entfield, (ast_expression*)value);
3247         if (!st) {
3248             ast_delete(entfield);
3249             return NULL;
3250         }
3251
3252         block = ast_block_new(ctx);
3253         if (!block) {
3254             ast_delete(st);
3255             return NULL;
3256         }
3257
3258         if (!ast_block_add_expr(block, (ast_expression*)st)) {
3259             ast_delete(block);
3260             return NULL;
3261         }
3262
3263         ret = ast_return_new(ctx, NULL);
3264         if (!ret) {
3265             ast_delete(block);
3266             return NULL;
3267         }
3268
3269         if (!ast_block_add_expr(block, (ast_expression*)ret)) {
3270             ast_delete(block);
3271             return NULL;
3272         }
3273
3274         return (ast_expression*)block;
3275     } else {
3276         ast_expression *left, *right;
3277         size_t diff = afterend - from;
3278         size_t middle = from + diff/2;
3279         left  = array_field_setter_node(parser, array, entity, index, value, from, middle);
3280         right = array_field_setter_node(parser, array, entity, index, value, middle, afterend);
3281         return array_accessor_split(parser, array, index, middle, left, right);
3282     }
3283 }
3284
3285 static ast_expression *array_getter_node(parser_t *parser, ast_value *array, ast_value *index, size_t from, size_t afterend)
3286 {
3287     lex_ctx ctx = ast_ctx(array);
3288
3289     if (from+1 == afterend) {
3290         ast_return      *ret;
3291         ast_array_index *subscript;
3292
3293         subscript = ast_array_index_new(ctx, (ast_expression*)array, (ast_expression*)parser_const_float(parser, from));
3294         if (!subscript)
3295             return NULL;
3296
3297         ret = ast_return_new(ctx, (ast_expression*)subscript);
3298         if (!ret) {
3299             ast_delete(subscript);
3300             return NULL;
3301         }
3302
3303         return (ast_expression*)ret;
3304     } else {
3305         ast_expression *left, *right;
3306         size_t diff = afterend - from;
3307         size_t middle = from + diff/2;
3308         left  = array_getter_node(parser, array, index, from, middle);
3309         right = array_getter_node(parser, array, index, middle, afterend);
3310         return array_accessor_split(parser, array, index, middle, left, right);
3311     }
3312 }
3313
3314 static bool parser_create_array_accessor(parser_t *parser, ast_value *array, const char *funcname, ast_value **out)
3315 {
3316     ast_function   *func = NULL;
3317     ast_value      *fval = NULL;
3318     ast_block      *body = NULL;
3319
3320     fval = ast_value_new(ast_ctx(array), funcname, TYPE_FUNCTION);
3321     if (!fval) {
3322         parseerror(parser, "failed to create accessor function value");
3323         return false;
3324     }
3325
3326     func = ast_function_new(ast_ctx(array), funcname, fval);
3327     if (!func) {
3328         ast_delete(fval);
3329         parseerror(parser, "failed to create accessor function node");
3330         return false;
3331     }
3332
3333     body = ast_block_new(ast_ctx(array));
3334     if (!body) {
3335         parseerror(parser, "failed to create block for array accessor");
3336         ast_delete(fval);
3337         ast_delete(func);
3338         return false;
3339     }
3340
3341     vec_push(func->blocks, body);
3342     *out = fval;
3343
3344     vec_push(parser->accessors, fval);
3345
3346     return true;
3347 }
3348
3349 static bool parser_create_array_setter(parser_t *parser, ast_value *array, const char *funcname)
3350 {
3351     ast_expression *root = NULL;
3352     ast_value      *index = NULL;
3353     ast_value      *value = NULL;
3354     ast_function   *func;
3355     ast_value      *fval;
3356
3357     if (!ast_istype(array->expression.next, ast_value)) {
3358         parseerror(parser, "internal error: array accessor needs to build an ast_value with a copy of the element type");
3359         return false;
3360     }
3361
3362     if (!parser_create_array_accessor(parser, array, funcname, &fval))
3363         return false;
3364     func = fval->constval.vfunc;
3365     fval->expression.next = (ast_expression*)ast_value_new(ast_ctx(array), "<void>", TYPE_VOID);
3366
3367     index = ast_value_new(ast_ctx(array), "index", TYPE_FLOAT);
3368     value = ast_value_copy((ast_value*)array->expression.next);
3369
3370     if (!index || !value) {
3371         parseerror(parser, "failed to create locals for array accessor");
3372         goto cleanup;
3373     }
3374     (void)!ast_value_set_name(value, "value"); /* not important */
3375     vec_push(fval->expression.params, index);
3376     vec_push(fval->expression.params, value);
3377
3378     root = array_setter_node(parser, array, index, value, 0, array->expression.count);
3379     if (!root) {
3380         parseerror(parser, "failed to build accessor search tree");
3381         goto cleanup;
3382     }
3383
3384     array->setter = fval;
3385     return ast_block_add_expr(func->blocks[0], root);
3386 cleanup:
3387     if (index) ast_delete(index);
3388     if (value) ast_delete(value);
3389     if (root)  ast_delete(root);
3390     ast_delete(func);
3391     ast_delete(fval);
3392     return false;
3393 }
3394
3395 static bool parser_create_array_field_setter(parser_t *parser, ast_value *array, const char *funcname)
3396 {
3397     ast_expression *root = NULL;
3398     ast_value      *entity = NULL;
3399     ast_value      *index = NULL;
3400     ast_value      *value = NULL;
3401     ast_function   *func;
3402     ast_value      *fval;
3403
3404     if (!ast_istype(array->expression.next, ast_value)) {
3405         parseerror(parser, "internal error: array accessor needs to build an ast_value with a copy of the element type");
3406         return false;
3407     }
3408
3409     if (!parser_create_array_accessor(parser, array, funcname, &fval))
3410         return false;
3411     func = fval->constval.vfunc;
3412     fval->expression.next = (ast_expression*)ast_value_new(ast_ctx(array), "<void>", TYPE_VOID);
3413
3414     entity = ast_value_new(ast_ctx(array), "entity", TYPE_ENTITY);
3415     index  = ast_value_new(ast_ctx(array), "index",  TYPE_FLOAT);
3416     value  = ast_value_copy((ast_value*)array->expression.next);
3417     if (!entity || !index || !value) {
3418         parseerror(parser, "failed to create locals for array accessor");
3419         goto cleanup;
3420     }
3421     (void)!ast_value_set_name(value, "value"); /* not important */
3422     vec_push(fval->expression.params, entity);
3423     vec_push(fval->expression.params, index);
3424     vec_push(fval->expression.params, value);
3425
3426     root = array_field_setter_node(parser, array, entity, index, value, 0, array->expression.count);
3427     if (!root) {
3428         parseerror(parser, "failed to build accessor search tree");
3429         goto cleanup;
3430     }
3431
3432     array->setter = fval;
3433     return ast_block_add_expr(func->blocks[0], root);
3434 cleanup:
3435     if (entity) ast_delete(entity);
3436     if (index)  ast_delete(index);
3437     if (value)  ast_delete(value);
3438     if (root)   ast_delete(root);
3439     ast_delete(func);
3440     ast_delete(fval);
3441     return false;
3442 }
3443
3444 static bool parser_create_array_getter(parser_t *parser, ast_value *array, const ast_expression *elemtype, const char *funcname)
3445 {
3446     ast_expression *root = NULL;
3447     ast_value      *index = NULL;
3448     ast_value      *fval;
3449     ast_function   *func;
3450
3451     /* NOTE: checking array->expression.next rather than elemtype since
3452      * for fields elemtype is a temporary fieldtype.
3453      */
3454     if (!ast_istype(array->expression.next, ast_value)) {
3455         parseerror(parser, "internal error: array accessor needs to build an ast_value with a copy of the element type");
3456         return false;
3457     }
3458
3459     if (!parser_create_array_accessor(parser, array, funcname, &fval))
3460         return false;
3461     func = fval->constval.vfunc;
3462     fval->expression.next = ast_type_copy(ast_ctx(array), elemtype);
3463
3464     index = ast_value_new(ast_ctx(array), "index", TYPE_FLOAT);
3465
3466     if (!index) {
3467         parseerror(parser, "failed to create locals for array accessor");
3468         goto cleanup;
3469     }
3470     vec_push(fval->expression.params, index);
3471
3472     root = array_getter_node(parser, array, index, 0, array->expression.count);
3473     if (!root) {
3474         parseerror(parser, "failed to build accessor search tree");
3475         goto cleanup;
3476     }
3477
3478     array->getter = fval;
3479     return ast_block_add_expr(func->blocks[0], root);
3480 cleanup:
3481     if (index) ast_delete(index);
3482     if (root)  ast_delete(root);
3483     ast_delete(func);
3484     ast_delete(fval);
3485     return false;
3486 }
3487
3488 static ast_value *parse_typename(parser_t *parser, ast_value **storebase, ast_value *cached_typedef);
3489 static ast_value *parse_parameter_list(parser_t *parser, ast_value *var)
3490 {
3491     lex_ctx     ctx;
3492     size_t      i;
3493     ast_value **params;
3494     ast_value  *param;
3495     ast_value  *fval;
3496     bool        first = true;
3497     bool        variadic = false;
3498
3499     ctx = parser_ctx(parser);
3500
3501     /* for the sake of less code we parse-in in this function */
3502     if (!parser_next(parser)) {
3503         parseerror(parser, "expected parameter list");
3504         return NULL;
3505     }
3506
3507     params = NULL;
3508
3509     /* parse variables until we hit a closing paren */
3510     while (parser->tok != ')') {
3511         if (!first) {
3512             /* there must be commas between them */
3513             if (parser->tok != ',') {
3514                 parseerror(parser, "expected comma or end of parameter list");
3515                 goto on_error;
3516             }
3517             if (!parser_next(parser)) {
3518                 parseerror(parser, "expected parameter");
3519                 goto on_error;
3520             }
3521         }
3522         first = false;
3523
3524         if (parser->tok == TOKEN_DOTS) {
3525             /* '...' indicates a varargs function */
3526             variadic = true;
3527             if (!parser_next(parser)) {
3528                 parseerror(parser, "expected parameter");
3529                 return NULL;
3530             }
3531             if (parser->tok != ')') {
3532                 parseerror(parser, "`...` must be the last parameter of a variadic function declaration");
3533                 goto on_error;
3534             }
3535         }
3536         else
3537         {
3538             /* for anything else just parse a typename */
3539             param = parse_typename(parser, NULL, NULL);
3540             if (!param)
3541                 goto on_error;
3542             vec_push(params, param);
3543             if (param->expression.vtype >= TYPE_VARIANT) {
3544                 char typename[1024];
3545                 ast_type_to_string((ast_expression*)param, typename, sizeof(typename));
3546                 parseerror(parser, "type not supported as part of a parameter list: %s", typename);
3547                 goto on_error;
3548             }
3549         }
3550     }
3551
3552     if (vec_size(params) == 1 && params[0]->expression.vtype == TYPE_VOID)
3553         vec_free(params);
3554
3555     /* sanity check */
3556     if (vec_size(params) > 8 && opts.standard == COMPILER_QCC)
3557         (void)!parsewarning(parser, WARN_EXTENSIONS, "more than 8 parameters are not supported by this standard");
3558
3559     /* parse-out */
3560     if (!parser_next(parser)) {
3561         parseerror(parser, "parse error after typename");
3562         goto on_error;
3563     }
3564
3565     /* now turn 'var' into a function type */
3566     fval = ast_value_new(ctx, "<type()>", TYPE_FUNCTION);
3567     fval->expression.next     = (ast_expression*)var;
3568     if (variadic)
3569         fval->expression.flags |= AST_FLAG_VARIADIC;
3570     var = fval;
3571
3572     var->expression.params = params;
3573     params = NULL;
3574
3575     return var;
3576
3577 on_error:
3578     ast_delete(var);
3579     for (i = 0; i < vec_size(params); ++i)
3580         ast_delete(params[i]);
3581     vec_free(params);
3582     return NULL;
3583 }
3584
3585 static ast_value *parse_arraysize(parser_t *parser, ast_value *var)
3586 {
3587     ast_expression *cexp;
3588     ast_value      *cval, *tmp;
3589     lex_ctx ctx;
3590
3591     ctx = parser_ctx(parser);
3592
3593     if (!parser_next(parser)) {
3594         ast_delete(var);
3595         parseerror(parser, "expected array-size");
3596         return NULL;
3597     }
3598
3599     cexp = parse_expression_leave(parser, true);
3600
3601     if (!cexp || !ast_istype(cexp, ast_value)) {
3602         if (cexp)
3603             ast_unref(cexp);
3604         ast_delete(var);
3605         parseerror(parser, "expected array-size as constant positive integer");
3606         return NULL;
3607     }
3608     cval = (ast_value*)cexp;
3609
3610     tmp = ast_value_new(ctx, "<type[]>", TYPE_ARRAY);
3611     tmp->expression.next = (ast_expression*)var;
3612     var = tmp;
3613
3614     if (cval->expression.vtype == TYPE_INTEGER)
3615         tmp->expression.count = cval->constval.vint;
3616     else if (cval->expression.vtype == TYPE_FLOAT)
3617         tmp->expression.count = cval->constval.vfloat;
3618     else {
3619         ast_unref(cexp);
3620         ast_delete(var);
3621         parseerror(parser, "array-size must be a positive integer constant");
3622         return NULL;
3623     }
3624     ast_unref(cexp);
3625
3626     if (parser->tok != ']') {
3627         ast_delete(var);
3628         parseerror(parser, "expected ']' after array-size");
3629         return NULL;
3630     }
3631     if (!parser_next(parser)) {
3632         ast_delete(var);
3633         parseerror(parser, "error after parsing array size");
3634         return NULL;
3635     }
3636     return var;
3637 }
3638
3639 /* Parse a complete typename.
3640  * for single-variables (ie. function parameters or typedefs) storebase should be NULL
3641  * but when parsing variables separated by comma
3642  * 'storebase' should point to where the base-type should be kept.
3643  * The base type makes up every bit of type information which comes *before* the
3644  * variable name.
3645  *
3646  * The following will be parsed in its entirety:
3647  *     void() foo()
3648  * The 'basetype' in this case is 'void()'
3649  * and if there's a comma after it, say:
3650  *     void() foo(), bar
3651  * then the type-information 'void()' can be stored in 'storebase'
3652  */
3653 static ast_value *parse_typename(parser_t *parser, ast_value **storebase, ast_value *cached_typedef)
3654 {
3655     ast_value *var, *tmp;
3656     lex_ctx    ctx;
3657
3658     const char *name = NULL;
3659     bool        isfield  = false;
3660     bool        wasarray = false;
3661     size_t      morefields = 0;
3662
3663     ctx = parser_ctx(parser);
3664
3665     /* types may start with a dot */
3666     if (parser->tok == '.') {
3667         isfield = true;
3668         /* if we parsed a dot we need a typename now */
3669         if (!parser_next(parser)) {
3670             parseerror(parser, "expected typename for field definition");
3671             return NULL;
3672         }
3673
3674         /* Further dots are handled seperately because they won't be part of the
3675          * basetype
3676          */
3677         while (parser->tok == '.') {
3678             ++morefields;
3679             if (!parser_next(parser)) {
3680                 parseerror(parser, "expected typename for field definition");
3681                 return NULL;
3682             }
3683         }
3684     }
3685     if (parser->tok == TOKEN_IDENT)
3686         cached_typedef = parser_find_typedef(parser, parser_tokval(parser), 0);
3687     if (!cached_typedef && parser->tok != TOKEN_TYPENAME) {
3688         parseerror(parser, "expected typename");
3689         return NULL;
3690     }
3691
3692     /* generate the basic type value */
3693     if (cached_typedef) {
3694         var = ast_value_copy(cached_typedef);
3695         ast_value_set_name(var, "<type(from_def)>");
3696     } else
3697         var = ast_value_new(ctx, "<type>", parser_token(parser)->constval.t);
3698
3699     for (; morefields; --morefields) {
3700         tmp = ast_value_new(ctx, "<.type>", TYPE_FIELD);
3701         tmp->expression.next = (ast_expression*)var;
3702         var = tmp;
3703     }
3704
3705     /* do not yet turn into a field - remember:
3706      * .void() foo; is a field too
3707      * .void()() foo; is a function
3708      */
3709
3710     /* parse on */
3711     if (!parser_next(parser)) {
3712         ast_delete(var);
3713         parseerror(parser, "parse error after typename");
3714         return NULL;
3715     }
3716
3717     /* an opening paren now starts the parameter-list of a function
3718      * this is where original-QC has parameter lists.
3719      * We allow a single parameter list here.
3720      * Much like fteqcc we don't allow `float()() x`
3721      */
3722     if (parser->tok == '(') {
3723         var = parse_parameter_list(parser, var);
3724         if (!var)
3725             return NULL;
3726     }
3727
3728     /* store the base if requested */
3729     if (storebase) {
3730         *storebase = ast_value_copy(var);
3731         if (isfield) {
3732             tmp = ast_value_new(ctx, "<type:f>", TYPE_FIELD);
3733             tmp->expression.next = (ast_expression*)*storebase;
3734             *storebase = tmp;
3735         }
3736     }
3737
3738     /* there may be a name now */
3739     if (parser->tok == TOKEN_IDENT) {
3740         name = util_strdup(parser_tokval(parser));
3741         /* parse on */
3742         if (!parser_next(parser)) {
3743             ast_delete(var);
3744             parseerror(parser, "error after variable or field declaration");
3745             return NULL;
3746         }
3747     }
3748
3749     /* now this may be an array */
3750     if (parser->tok == '[') {
3751         wasarray = true;
3752         var = parse_arraysize(parser, var);
3753         if (!var)
3754             return NULL;
3755     }
3756
3757     /* This is the point where we can turn it into a field */
3758     if (isfield) {
3759         /* turn it into a field if desired */
3760         tmp = ast_value_new(ctx, "<type:f>", TYPE_FIELD);
3761         tmp->expression.next = (ast_expression*)var;
3762         var = tmp;
3763     }
3764
3765     /* now there may be function parens again */
3766     if (parser->tok == '(' && opts.standard == COMPILER_QCC)
3767         parseerror(parser, "C-style function syntax is not allowed in -std=qcc");
3768     if (parser->tok == '(' && wasarray)
3769         parseerror(parser, "arrays as part of a return type is not supported");
3770     while (parser->tok == '(') {
3771         var = parse_parameter_list(parser, var);
3772         if (!var) {
3773             if (name)
3774                 mem_d((void*)name);
3775             ast_delete(var);
3776             return NULL;
3777         }
3778     }
3779
3780     /* finally name it */
3781     if (name) {
3782         if (!ast_value_set_name(var, name)) {
3783             ast_delete(var);
3784             parseerror(parser, "internal error: failed to set name");
3785             return NULL;
3786         }
3787         /* free the name, ast_value_set_name duplicates */
3788         mem_d((void*)name);
3789     }
3790
3791     return var;
3792 }
3793
3794 static bool parse_typedef(parser_t *parser)
3795 {
3796     ast_value      *typevar, *oldtype;
3797     ast_expression *old;
3798
3799     typevar = parse_typename(parser, NULL, NULL);
3800
3801     if (!typevar)
3802         return false;
3803
3804     if ( (old = parser_find_var(parser, typevar->name)) ) {
3805         parseerror(parser, "cannot define a type with the same name as a variable: %s\n"
3806                    " -> `%s` has been declared here: %s:%i",
3807                    typevar->name, ast_ctx(old).file, ast_ctx(old).line);
3808         ast_delete(typevar);
3809         return false;
3810     }
3811
3812     if ( (oldtype = parser_find_typedef(parser, typevar->name, vec_last(parser->_blocktypedefs))) ) {
3813         parseerror(parser, "type `%s` has already been declared here: %s:%i",
3814                    typevar->name, ast_ctx(oldtype).file, ast_ctx(oldtype).line);
3815         ast_delete(typevar);
3816         return false;
3817     }
3818
3819     vec_push(parser->_typedefs, typevar);
3820     util_htset(vec_last(parser->typedefs), typevar->name, typevar);
3821
3822     if (parser->tok != ';') {
3823         parseerror(parser, "expected semicolon after typedef");
3824         return false;
3825     }
3826     if (!parser_next(parser)) {
3827         parseerror(parser, "parse error after typedef");
3828         return false;
3829     }
3830
3831     return true;
3832 }
3833
3834 static bool parse_variable(parser_t *parser, ast_block *localblock, bool nofields, int qualifier, ast_value *cached_typedef, bool noref, bool noreturn)
3835 {
3836     ast_value *var;
3837     ast_value *proto;
3838     ast_expression *old;
3839     bool       was_end;
3840     size_t     i;
3841
3842     ast_value *basetype = NULL;
3843     bool      retval    = true;
3844     bool      isparam   = false;
3845     bool      isvector  = false;
3846     bool      cleanvar  = true;
3847     bool      wasarray  = false;
3848
3849     ast_member *me[3];
3850
3851     /* get the first complete variable */
3852     var = parse_typename(parser, &basetype, cached_typedef);
3853     if (!var) {
3854         if (basetype)
3855             ast_delete(basetype);
3856         return false;
3857     }
3858
3859     while (true) {
3860         proto = NULL;
3861         wasarray = false;
3862
3863         /* Part 0: finish the type */
3864         if (parser->tok == '(') {
3865             if (opts.standard == COMPILER_QCC)
3866                 parseerror(parser, "C-style function syntax is not allowed in -std=qcc");
3867             var = parse_parameter_list(parser, var);
3868             if (!var) {
3869                 retval = false;
3870                 goto cleanup;
3871             }
3872         }
3873         /* we only allow 1-dimensional arrays */
3874         if (parser->tok == '[') {
3875             wasarray = true;
3876             var = parse_arraysize(parser, var);
3877             if (!var) {
3878                 retval = false;
3879                 goto cleanup;
3880             }
3881         }
3882         if (parser->tok == '(' && wasarray) {
3883             parseerror(parser, "arrays as part of a return type is not supported");
3884             /* we'll still parse the type completely for now */
3885         }
3886         /* for functions returning functions */
3887         while (parser->tok == '(') {
3888             if (opts.standard == COMPILER_QCC)
3889                 parseerror(parser, "C-style function syntax is not allowed in -std=qcc");
3890             var = parse_parameter_list(parser, var);
3891             if (!var) {
3892                 retval = false;
3893                 goto cleanup;
3894             }
3895         }
3896
3897         var->cvq = qualifier;
3898         /* in a noref section we simply bump the usecount */
3899         if (noref || parser->noref)
3900             var->uses++;
3901         if (noreturn)
3902             var->expression.flags |= AST_FLAG_NORETURN;
3903
3904         /* Part 1:
3905          * check for validity: (end_sys_..., multiple-definitions, prototypes, ...)
3906          * Also: if there was a prototype, `var` will be deleted and set to `proto` which
3907          * is then filled with the previous definition and the parameter-names replaced.
3908          */
3909         if (!localblock) {
3910             /* Deal with end_sys_ vars */
3911             was_end = false;
3912             if (!strcmp(var->name, "end_sys_globals")) {
3913                 var->uses++;
3914                 parser->crc_globals = vec_size(parser->globals);
3915                 was_end = true;
3916             }
3917             else if (!strcmp(var->name, "end_sys_fields")) {
3918                 var->uses++;
3919                 parser->crc_fields = vec_size(parser->fields);
3920                 was_end = true;
3921             }
3922             if (was_end && var->expression.vtype == TYPE_FIELD) {
3923                 if (parsewarning(parser, WARN_END_SYS_FIELDS,
3924                                  "global '%s' hint should not be a field",
3925                                  parser_tokval(parser)))
3926                 {
3927                     retval = false;
3928                     goto cleanup;
3929                 }
3930             }
3931
3932             if (!nofields && var->expression.vtype == TYPE_FIELD)
3933             {
3934                 /* deal with field declarations */
3935                 old = parser_find_field(parser, var->name);
3936                 if (old) {
3937                     if (parsewarning(parser, WARN_FIELD_REDECLARED, "field `%s` already declared here: %s:%i",
3938                                      var->name, ast_ctx(old).file, (int)ast_ctx(old).line))
3939                     {
3940                         retval = false;
3941                         goto cleanup;
3942                     }
3943                     ast_delete(var);
3944                     var = NULL;
3945                     goto skipvar;
3946                     /*
3947                     parseerror(parser, "field `%s` already declared here: %s:%i",
3948                                var->name, ast_ctx(old).file, ast_ctx(old).line);
3949                     retval = false;
3950                     goto cleanup;
3951                     */
3952                 }
3953                 if (opts.standard == COMPILER_QCC &&
3954                     (old = parser_find_global(parser, var->name)))
3955                 {
3956                     parseerror(parser, "cannot declare a field and a global of the same name with -std=qcc");
3957                     parseerror(parser, "field `%s` already declared here: %s:%i",
3958                                var->name, ast_ctx(old).file, ast_ctx(old).line);
3959                     retval = false;
3960                     goto cleanup;
3961                 }
3962             }
3963             else
3964             {
3965                 /* deal with other globals */
3966                 old = parser_find_global(parser, var->name);
3967                 if (old && var->expression.vtype == TYPE_FUNCTION && old->expression.vtype == TYPE_FUNCTION)
3968                 {
3969                     /* This is a function which had a prototype */
3970                     if (!ast_istype(old, ast_value)) {
3971                         parseerror(parser, "internal error: prototype is not an ast_value");
3972                         retval = false;
3973                         goto cleanup;
3974                     }
3975                     proto = (ast_value*)old;
3976                     if (!ast_compare_type((ast_expression*)proto, (ast_expression*)var)) {
3977                         parseerror(parser, "conflicting types for `%s`, previous declaration was here: %s:%i",
3978                                    proto->name,
3979                                    ast_ctx(proto).file, ast_ctx(proto).line);
3980                         retval = false;
3981                         goto cleanup;
3982                     }
3983                     /* we need the new parameter-names */
3984                     for (i = 0; i < vec_size(proto->expression.params); ++i)
3985                         ast_value_set_name(proto->expression.params[i], var->expression.params[i]->name);
3986                     ast_delete(var);
3987                     var = proto;
3988                 }
3989                 else
3990                 {
3991                     /* other globals */
3992                     if (old) {
3993                         if (opts.standard == COMPILER_GMQCC) {
3994                             parseerror(parser, "global `%s` already declared here: %s:%i",
3995                                        var->name, ast_ctx(old).file, ast_ctx(old).line);
3996                             retval = false;
3997                             goto cleanup;
3998                         } else {
3999                             if (parsewarning(parser, WARN_DOUBLE_DECLARATION,
4000                                              "global `%s` already declared here: %s:%i",
4001                                              var->name, ast_ctx(old).file, ast_ctx(old).line))
4002                             {
4003                                 retval = false;
4004                                 goto cleanup;
4005                             }
4006                             proto = (ast_value*)old;
4007                             if (!ast_istype(old, ast_value)) {
4008                                 parseerror(parser, "internal error: not an ast_value");
4009                                 retval = false;
4010                                 proto = NULL;
4011                                 goto cleanup;
4012                             }
4013                             ast_delete(var);
4014                             var = proto;
4015                         }
4016                     }
4017                     if (opts.standard == COMPILER_QCC &&
4018                         (old = parser_find_field(parser, var->name)))
4019                     {
4020                         parseerror(parser, "cannot declare a field and a global of the same name with -std=qcc");
4021                         parseerror(parser, "global `%s` already declared here: %s:%i",
4022                                    var->name, ast_ctx(old).file, ast_ctx(old).line);
4023                         retval = false;
4024                         goto cleanup;
4025                     }
4026                 }
4027             }
4028         }
4029         else /* it's not a global */
4030         {
4031             old = parser_find_local(parser, var->name, vec_size(parser->variables)-1, &isparam);
4032             if (old && !isparam) {
4033                 parseerror(parser, "local `%s` already declared here: %s:%i",
4034                            var->name, ast_ctx(old).file, (int)ast_ctx(old).line);
4035                 retval = false;
4036                 goto cleanup;
4037             }
4038             old = parser_find_local(parser, var->name, 0, &isparam);
4039             if (old && isparam) {
4040                 if (parsewarning(parser, WARN_LOCAL_SHADOWS,
4041                                  "local `%s` is shadowing a parameter", var->name))
4042                 {
4043                     parseerror(parser, "local `%s` already declared here: %s:%i",
4044                                var->name, ast_ctx(old).file, (int)ast_ctx(old).line);
4045                     retval = false;
4046                     goto cleanup;
4047                 }
4048                 if (opts.standard != COMPILER_GMQCC) {
4049                     ast_delete(var);
4050                     var = NULL;
4051                     goto skipvar;
4052                 }
4053             }
4054         }
4055
4056         /* Part 2:
4057          * Create the global/local, and deal with vector types.
4058          */
4059         if (!proto) {
4060             if (var->expression.vtype == TYPE_VECTOR)
4061                 isvector = true;
4062             else if (var->expression.vtype == TYPE_FIELD &&
4063                      var->expression.next->expression.vtype == TYPE_VECTOR)
4064                 isvector = true;
4065
4066             if (isvector) {
4067                 if (!create_vector_members(var, me)) {
4068                     retval = false;
4069                     goto cleanup;
4070                 }
4071             }
4072
4073             if (!localblock) {
4074                 /* deal with global variables, fields, functions */
4075                 if (!nofields && var->expression.vtype == TYPE_FIELD && parser->tok != '=') {
4076                     var->isfield = true;
4077                     vec_push(parser->fields, (ast_expression*)var);
4078                     util_htset(parser->htfields, var->name, var);
4079                     if (isvector) {
4080                         for (i = 0; i < 3; ++i) {
4081                             vec_push(parser->fields, (ast_expression*)me[i]);
4082                             util_htset(parser->htfields, me[i]->name, me[i]);
4083                         }
4084                     }
4085                 }
4086                 else {
4087                     vec_push(parser->globals, (ast_expression*)var);
4088                     util_htset(parser->htglobals, var->name, var);
4089                     if (isvector) {
4090                         for (i = 0; i < 3; ++i) {
4091                             vec_push(parser->globals, (ast_expression*)me[i]);
4092                             util_htset(parser->htglobals, me[i]->name, me[i]);
4093                         }
4094                     }
4095                 }
4096             } else {
4097                 vec_push(localblock->locals, var);
4098                 parser_addlocal(parser, var->name, (ast_expression*)var);
4099                 if (isvector) {
4100                     for (i = 0; i < 3; ++i) {
4101                         parser_addlocal(parser, me[i]->name, (ast_expression*)me[i]);
4102                         ast_block_collect(localblock, (ast_expression*)me[i]);
4103                     }
4104                 }
4105             }
4106
4107         }
4108         me[0] = me[1] = me[2] = NULL;
4109         cleanvar = false;
4110         /* Part 2.2
4111          * deal with arrays
4112          */
4113         if (var->expression.vtype == TYPE_ARRAY) {
4114             char name[1024];
4115             snprintf(name, sizeof(name), "%s##SET", var->name);
4116             if (!parser_create_array_setter(parser, var, name))
4117                 goto cleanup;
4118             snprintf(name, sizeof(name), "%s##GET", var->name);
4119             if (!parser_create_array_getter(parser, var, var->expression.next, name))
4120                 goto cleanup;
4121         }
4122         else if (!localblock && !nofields &&
4123                  var->expression.vtype == TYPE_FIELD &&
4124                  var->expression.next->expression.vtype == TYPE_ARRAY)
4125         {
4126             char name[1024];
4127             ast_expression *telem;
4128             ast_value      *tfield;
4129             ast_value      *array = (ast_value*)var->expression.next;
4130
4131             if (!ast_istype(var->expression.next, ast_value)) {
4132                 parseerror(parser, "internal error: field element type must be an ast_value");
4133                 goto cleanup;
4134             }
4135
4136             snprintf(name, sizeof(name), "%s##SETF", var->name);
4137             if (!parser_create_array_field_setter(parser, array, name))
4138                 goto cleanup;
4139
4140             telem = ast_type_copy(ast_ctx(var), array->expression.next);
4141             tfield = ast_value_new(ast_ctx(var), "<.type>", TYPE_FIELD);
4142             tfield->expression.next = telem;
4143             snprintf(name, sizeof(name), "%s##GETFP", var->name);
4144             if (!parser_create_array_getter(parser, array, (ast_expression*)tfield, name)) {
4145                 ast_delete(tfield);
4146                 goto cleanup;
4147             }
4148             ast_delete(tfield);
4149         }
4150
4151 skipvar:
4152         if (parser->tok == ';') {
4153             ast_delete(basetype);
4154             if (!parser_next(parser)) {
4155                 parseerror(parser, "error after variable declaration");
4156                 return false;
4157             }
4158             return true;
4159         }
4160
4161         if (parser->tok == ',')
4162             goto another;
4163
4164         /*
4165         if (!var || (!localblock && !nofields && basetype->expression.vtype == TYPE_FIELD)) {
4166         */
4167         if (!var) {
4168             parseerror(parser, "missing comma or semicolon while parsing variables");
4169             break;
4170         }
4171
4172         if (localblock && opts.standard == COMPILER_QCC) {
4173             if (parsewarning(parser, WARN_LOCAL_CONSTANTS,
4174                              "initializing expression turns variable `%s` into a constant in this standard",
4175                              var->name) )
4176             {
4177                 break;
4178             }
4179         }
4180
4181         if (parser->tok != '{') {
4182             if (parser->tok != '=') {
4183                 parseerror(parser, "missing semicolon or initializer, got: `%s`", parser_tokval(parser));
4184                 break;
4185             }
4186
4187             if (!parser_next(parser)) {
4188                 parseerror(parser, "error parsing initializer");
4189                 break;
4190             }
4191         }
4192         else if (opts.standard == COMPILER_QCC) {
4193             parseerror(parser, "expected '=' before function body in this standard");
4194         }
4195
4196         if (parser->tok == '#') {
4197             ast_function *func = NULL;
4198
4199             if (localblock) {
4200                 parseerror(parser, "cannot declare builtins within functions");
4201                 break;
4202             }
4203             if (var->expression.vtype != TYPE_FUNCTION) {
4204                 parseerror(parser, "unexpected builtin number, '%s' is not a function", var->name);
4205                 break;
4206             }
4207             if (!parser_next(parser)) {
4208                 parseerror(parser, "expected builtin number");
4209                 break;
4210             }
4211             if (parser->tok != TOKEN_INTCONST) {
4212                 parseerror(parser, "builtin number must be an integer constant");
4213                 break;
4214             }
4215             if (parser_token(parser)->constval.i < 0) {
4216                 parseerror(parser, "builtin number must be an integer greater than zero");
4217                 break;
4218             }
4219
4220             if (var->hasvalue) {
4221                 (void)!parsewarning(parser, WARN_DOUBLE_DECLARATION,
4222                                     "builtin `%s` has already been defined\n"
4223                                     " -> previous declaration here: %s:%i",
4224                                     var->name, ast_ctx(var).file, (int)ast_ctx(var).line);
4225             }
4226             else
4227             {
4228                 func = ast_function_new(ast_ctx(var), var->name, var);
4229                 if (!func) {
4230                     parseerror(parser, "failed to allocate function for `%s`", var->name);
4231                     break;
4232                 }
4233                 vec_push(parser->functions, func);
4234
4235                 func->builtin = -parser_token(parser)->constval.i-1;
4236             }
4237
4238             if (!parser_next(parser)) {
4239                 parseerror(parser, "expected comma or semicolon");
4240                 if (func)
4241                     ast_function_delete(func);
4242                 var->constval.vfunc = NULL;
4243                 break;
4244             }
4245         }
4246         else if (parser->tok == '{' || parser->tok == '[')
4247         {
4248             size_t i;
4249             if (localblock) {
4250                 parseerror(parser, "cannot declare functions within functions");
4251                 break;
4252             }
4253
4254             if (proto)
4255                 ast_ctx(proto) = parser_ctx(parser);
4256
4257             if (!parse_function_body(parser, var))
4258                 break;
4259             ast_delete(basetype);
4260             for (i = 0; i < vec_size(parser->gotos); ++i)
4261                 parseerror(parser, "undefined label: `%s`", parser->gotos[i]->name);
4262             vec_free(parser->gotos);
4263             vec_free(parser->labels);
4264             return true;
4265         } else {
4266             ast_expression *cexp;
4267             ast_value      *cval;
4268
4269             cexp = parse_expression_leave(parser, true);
4270             if (!cexp)
4271                 break;
4272
4273             if (!localblock) {
4274                 cval = (ast_value*)cexp;
4275                 if (!ast_istype(cval, ast_value) || ((!cval->hasvalue || cval->cvq != CV_CONST) && !cval->isfield))
4276                     parseerror(parser, "cannot initialize a global constant variable with a non-constant expression");
4277                 else
4278                 {
4279                     if (opts.standard != COMPILER_GMQCC &&
4280                         !OPTS_FLAG(INITIALIZED_NONCONSTANTS) &&
4281                         qualifier != CV_VAR)
4282                     {
4283                         var->cvq = CV_CONST;
4284                     }
4285                     var->hasvalue = true;
4286                     if (cval->expression.vtype == TYPE_STRING)
4287                         var->constval.vstring = parser_strdup(cval->constval.vstring);
4288                     else if (cval->expression.vtype == TYPE_FIELD)
4289                         var->constval.vfield = cval;
4290                     else
4291                         memcpy(&var->constval, &cval->constval, sizeof(var->constval));
4292                     ast_unref(cval);
4293                 }
4294             } else {
4295                 bool cvq;
4296                 shunt sy = { NULL, NULL };
4297                 cvq = var->cvq;
4298                 var->cvq = CV_NONE;
4299                 vec_push(sy.out, syexp(ast_ctx(var), (ast_expression*)var));
4300                 vec_push(sy.out, syexp(ast_ctx(cexp), (ast_expression*)cexp));
4301                 vec_push(sy.ops, syop(ast_ctx(var), parser->assign_op));
4302                 if (!parser_sy_apply_operator(parser, &sy))
4303                     ast_unref(cexp);
4304                 else {
4305                     if (vec_size(sy.out) != 1 && vec_size(sy.ops) != 0)
4306                         parseerror(parser, "internal error: leaked operands");
4307                     if (!ast_block_add_expr(localblock, (ast_expression*)sy.out[0].out))
4308                         break;
4309                 }
4310                 vec_free(sy.out);
4311                 vec_free(sy.ops);
4312                 var->cvq = cvq;
4313             }
4314         }
4315
4316 another:
4317         if (parser->tok == ',') {
4318             if (!parser_next(parser)) {
4319                 parseerror(parser, "expected another variable");
4320                 break;
4321             }
4322
4323             if (parser->tok != TOKEN_IDENT) {
4324                 parseerror(parser, "expected another variable");
4325                 break;
4326             }
4327             var = ast_value_copy(basetype);
4328             cleanvar = true;
4329             ast_value_set_name(var, parser_tokval(parser));
4330             if (!parser_next(parser)) {
4331                 parseerror(parser, "error parsing variable declaration");
4332                 break;
4333             }
4334             continue;
4335         }
4336
4337         if (parser->tok != ';') {
4338             parseerror(parser, "missing semicolon after variables");
4339             break;
4340         }
4341
4342         if (!parser_next(parser)) {
4343             parseerror(parser, "parse error after variable declaration");
4344             break;
4345         }
4346
4347         ast_delete(basetype);
4348         return true;
4349     }
4350
4351     if (cleanvar && var)
4352         ast_delete(var);
4353     ast_delete(basetype);
4354     return false;
4355
4356 cleanup:
4357     ast_delete(basetype);
4358     if (cleanvar && var)
4359         ast_delete(var);
4360     if (me[0]) ast_member_delete(me[0]);
4361     if (me[1]) ast_member_delete(me[1]);
4362     if (me[2]) ast_member_delete(me[2]);
4363     return retval;
4364 }
4365
4366 static bool parser_global_statement(parser_t *parser)
4367 {
4368     int        cvq      = CV_WRONG;
4369     bool       noref    = false;
4370     bool       noreturn = false;
4371     ast_value *istype   = NULL;
4372
4373     if (parser->tok == TOKEN_IDENT)
4374         istype = parser_find_typedef(parser, parser_tokval(parser), 0);
4375
4376     if (istype || parser->tok == TOKEN_TYPENAME || parser->tok == '.')
4377     {
4378         return parse_variable(parser, NULL, false, CV_NONE, istype, false, false);
4379     }
4380     else if (parse_var_qualifiers(parser, false, &cvq, &noref, &noreturn))
4381     {
4382         if (cvq == CV_WRONG)
4383             return false;
4384         return parse_variable(parser, NULL, true, cvq, NULL, noref, noreturn);
4385     }
4386     else if (parser->tok == TOKEN_KEYWORD)
4387     {
4388         if (!strcmp(parser_tokval(parser), "typedef")) {
4389             if (!parser_next(parser)) {
4390                 parseerror(parser, "expected type definition after 'typedef'");
4391                 return false;
4392             }
4393             return parse_typedef(parser);
4394         }
4395         parseerror(parser, "unrecognized keyword `%s`", parser_tokval(parser));
4396         return false;
4397     }
4398     else if (parser->tok == '#')
4399     {
4400         return parse_pragma(parser);
4401     }
4402     else if (parser->tok == '$')
4403     {
4404         if (!parser_next(parser)) {
4405             parseerror(parser, "parse error");
4406             return false;
4407         }
4408     }
4409     else
4410     {
4411         parseerror(parser, "unexpected token: %s", parser->lex->tok.value);
4412         return false;
4413     }
4414     return true;
4415 }
4416
4417 static uint16_t progdefs_crc_sum(uint16_t old, const char *str)
4418 {
4419     return util_crc16(old, str, strlen(str));
4420 }
4421
4422 static void progdefs_crc_file(const char *str)
4423 {
4424     /* write to progdefs.h here */
4425     (void)str;
4426 }
4427
4428 static uint16_t progdefs_crc_both(uint16_t old, const char *str)
4429 {
4430     old = progdefs_crc_sum(old, str);
4431     progdefs_crc_file(str);
4432     return old;
4433 }
4434
4435 static void generate_checksum(parser_t *parser)
4436 {
4437     uint16_t   crc = 0xFFFF;
4438     size_t     i;
4439     ast_value *value;
4440
4441         crc = progdefs_crc_both(crc, "\n/* file generated by qcc, do not modify */\n\ntypedef struct\n{");
4442         crc = progdefs_crc_sum(crc, "\tint\tpad[28];\n");
4443         /*
4444         progdefs_crc_file("\tint\tpad;\n");
4445         progdefs_crc_file("\tint\tofs_return[3];\n");
4446         progdefs_crc_file("\tint\tofs_parm0[3];\n");
4447         progdefs_crc_file("\tint\tofs_parm1[3];\n");
4448         progdefs_crc_file("\tint\tofs_parm2[3];\n");
4449         progdefs_crc_file("\tint\tofs_parm3[3];\n");
4450         progdefs_crc_file("\tint\tofs_parm4[3];\n");
4451         progdefs_crc_file("\tint\tofs_parm5[3];\n");
4452         progdefs_crc_file("\tint\tofs_parm6[3];\n");
4453         progdefs_crc_file("\tint\tofs_parm7[3];\n");
4454         */
4455         for (i = 0; i < parser->crc_globals; ++i) {
4456             if (!ast_istype(parser->globals[i], ast_value))
4457                 continue;
4458             value = (ast_value*)(parser->globals[i]);
4459             switch (value->expression.vtype) {
4460                 case TYPE_FLOAT:    crc = progdefs_crc_both(crc, "\tfloat\t"); break;
4461                 case TYPE_VECTOR:   crc = progdefs_crc_both(crc, "\tvec3_t\t"); break;
4462                 case TYPE_STRING:   crc = progdefs_crc_both(crc, "\tstring_t\t"); break;
4463                 case TYPE_FUNCTION: crc = progdefs_crc_both(crc, "\tfunc_t\t"); break;
4464                 default:
4465                     crc = progdefs_crc_both(crc, "\tint\t");
4466                     break;
4467             }
4468             crc = progdefs_crc_both(crc, value->name);
4469             crc = progdefs_crc_both(crc, ";\n");
4470         }
4471         crc = progdefs_crc_both(crc, "} globalvars_t;\n\ntypedef struct\n{\n");
4472         for (i = 0; i < parser->crc_fields; ++i) {
4473             if (!ast_istype(parser->fields[i], ast_value))
4474                 continue;
4475             value = (ast_value*)(parser->fields[i]);
4476             switch (value->expression.next->expression.vtype) {
4477                 case TYPE_FLOAT:    crc = progdefs_crc_both(crc, "\tfloat\t"); break;
4478                 case TYPE_VECTOR:   crc = progdefs_crc_both(crc, "\tvec3_t\t"); break;
4479                 case TYPE_STRING:   crc = progdefs_crc_both(crc, "\tstring_t\t"); break;
4480                 case TYPE_FUNCTION: crc = progdefs_crc_both(crc, "\tfunc_t\t"); break;
4481                 default:
4482                     crc = progdefs_crc_both(crc, "\tint\t");
4483                     break;
4484             }
4485             crc = progdefs_crc_both(crc, value->name);
4486             crc = progdefs_crc_both(crc, ";\n");
4487         }
4488         crc = progdefs_crc_both(crc, "} entvars_t;\n\n");
4489
4490         code_crc = crc;
4491 }
4492
4493 static parser_t *parser;
4494
4495 bool parser_init()
4496 {
4497     size_t i;
4498
4499     parser = (parser_t*)mem_a(sizeof(parser_t));
4500     if (!parser)
4501         return false;
4502
4503     memset(parser, 0, sizeof(*parser));
4504
4505     for (i = 0; i < operator_count; ++i) {
4506         if (operators[i].id == opid1('=')) {
4507             parser->assign_op = operators+i;
4508             break;
4509         }
4510     }
4511     if (!parser->assign_op) {
4512         printf("internal error: initializing parser: failed to find assign operator\n");
4513         mem_d(parser);
4514         return false;
4515     }
4516
4517     vec_push(parser->variables, parser->htfields  = util_htnew(PARSER_HT_SIZE));
4518     vec_push(parser->variables, parser->htglobals = util_htnew(PARSER_HT_SIZE));
4519     vec_push(parser->typedefs, util_htnew(TYPEDEF_HT_SIZE));
4520     vec_push(parser->_blocktypedefs, 0);
4521     return true;
4522 }
4523
4524 bool parser_compile()
4525 {
4526     /* initial lexer/parser state */
4527     parser->lex->flags.noops = true;
4528
4529     if (parser_next(parser))
4530     {
4531         while (parser->tok != TOKEN_EOF && parser->tok < TOKEN_ERROR)
4532         {
4533             if (!parser_global_statement(parser)) {
4534                 if (parser->tok == TOKEN_EOF)
4535                     parseerror(parser, "unexpected eof");
4536                 else if (!parser->errors)
4537                     parseerror(parser, "there have been errors, bailing out");
4538                 lex_close(parser->lex);
4539                 parser->lex = NULL;
4540                 return false;
4541             }
4542         }
4543     } else {
4544         parseerror(parser, "parse error");
4545         lex_close(parser->lex);
4546         parser->lex = NULL;
4547         return false;
4548     }
4549
4550     lex_close(parser->lex);
4551     parser->lex = NULL;
4552
4553     return !parser->errors;
4554 }
4555
4556 bool parser_compile_file(const char *filename)
4557 {
4558     parser->lex = lex_open(filename);
4559     if (!parser->lex) {
4560         con_err("failed to open file \"%s\"\n", filename);
4561         return false;
4562     }
4563     return parser_compile();
4564 }
4565
4566 bool parser_compile_string_len(const char *name, const char *str, size_t len)
4567 {
4568     parser->lex = lex_open_string(str, len, name);
4569     if (!parser->lex) {
4570         con_err("failed to create lexer for string \"%s\"\n", name);
4571         return false;
4572     }
4573     return parser_compile();
4574 }
4575
4576 bool parser_compile_string(const char *name, const char *str)
4577 {
4578     parser->lex = lex_open_string(str, strlen(str), name);
4579     if (!parser->lex) {
4580         con_err("failed to create lexer for string \"%s\"\n", name);
4581         return false;
4582     }
4583     return parser_compile();
4584 }
4585
4586 void parser_cleanup()
4587 {
4588     size_t i;
4589     for (i = 0; i < vec_size(parser->accessors); ++i) {
4590         ast_delete(parser->accessors[i]->constval.vfunc);
4591         parser->accessors[i]->constval.vfunc = NULL;
4592         ast_delete(parser->accessors[i]);
4593     }
4594     for (i = 0; i < vec_size(parser->functions); ++i) {
4595         ast_delete(parser->functions[i]);
4596     }
4597     for (i = 0; i < vec_size(parser->imm_vector); ++i) {
4598         ast_delete(parser->imm_vector[i]);
4599     }
4600     for (i = 0; i < vec_size(parser->imm_string); ++i) {
4601         ast_delete(parser->imm_string[i]);
4602     }
4603     for (i = 0; i < vec_size(parser->imm_float); ++i) {
4604         ast_delete(parser->imm_float[i]);
4605     }
4606     for (i = 0; i < vec_size(parser->fields); ++i) {
4607         ast_delete(parser->fields[i]);
4608     }
4609     for (i = 0; i < vec_size(parser->globals); ++i) {
4610         ast_delete(parser->globals[i]);
4611     }
4612     vec_free(parser->accessors);
4613     vec_free(parser->functions);
4614     vec_free(parser->imm_vector);
4615     vec_free(parser->imm_string);
4616     vec_free(parser->imm_float);
4617     vec_free(parser->globals);
4618     vec_free(parser->fields);
4619
4620     for (i = 0; i < vec_size(parser->variables); ++i)
4621         util_htdel(parser->variables[i]);
4622     vec_free(parser->variables);
4623     vec_free(parser->_blocklocals);
4624     vec_free(parser->_locals);
4625
4626     for (i = 0; i < vec_size(parser->_typedefs); ++i)
4627         ast_delete(parser->_typedefs[i]);
4628     vec_free(parser->_typedefs);
4629     for (i = 0; i < vec_size(parser->typedefs); ++i)
4630         util_htdel(parser->typedefs[i]);
4631     vec_free(parser->typedefs);
4632     vec_free(parser->_blocktypedefs);
4633
4634     vec_free(parser->_block_ctx);
4635
4636     vec_free(parser->labels);
4637     vec_free(parser->gotos);
4638
4639     mem_d(parser);
4640 }
4641
4642 bool parser_finish(const char *output)
4643 {
4644     size_t i;
4645     ir_builder *ir;
4646     bool retval = true;
4647
4648     if (!parser->errors)
4649     {
4650         ir = ir_builder_new("gmqcc_out");
4651         if (!ir) {
4652             con_out("failed to allocate builder\n");
4653             return false;
4654         }
4655
4656         for (i = 0; i < vec_size(parser->fields); ++i) {
4657             ast_value *field;
4658             bool hasvalue;
4659             if (!ast_istype(parser->fields[i], ast_value))
4660                 continue;
4661             field = (ast_value*)parser->fields[i];
4662             hasvalue = field->hasvalue;
4663             field->hasvalue = false;
4664             if (!ast_global_codegen((ast_value*)field, ir, true)) {
4665                 con_out("failed to generate field %s\n", field->name);
4666                 ir_builder_delete(ir);
4667                 return false;
4668             }
4669             if (hasvalue) {
4670                 ir_value *ifld;
4671                 ast_expression *subtype;
4672                 field->hasvalue = true;
4673                 subtype = field->expression.next;
4674                 ifld = ir_builder_create_field(ir, field->name, subtype->expression.vtype);
4675                 if (subtype->expression.vtype == TYPE_FIELD)
4676                     ifld->fieldtype = subtype->expression.next->expression.vtype;
4677                 else if (subtype->expression.vtype == TYPE_FUNCTION)
4678                     ifld->outtype = subtype->expression.next->expression.vtype;
4679                 (void)!ir_value_set_field(field->ir_v, ifld);
4680             }
4681         }
4682         for (i = 0; i < vec_size(parser->globals); ++i) {
4683             ast_value *asvalue;
4684             if (!ast_istype(parser->globals[i], ast_value))
4685                 continue;
4686             asvalue = (ast_value*)(parser->globals[i]);
4687             if (!asvalue->uses && !asvalue->hasvalue && asvalue->expression.vtype != TYPE_FUNCTION) {
4688                 retval = retval && !genwarning(ast_ctx(asvalue), WARN_UNUSED_VARIABLE,
4689                                                "unused global: `%s`", asvalue->name);
4690             }
4691             if (!ast_global_codegen(asvalue, ir, false)) {
4692                 con_out("failed to generate global %s\n", asvalue->name);
4693                 ir_builder_delete(ir);
4694                 return false;
4695             }
4696         }
4697         for (i = 0; i < vec_size(parser->imm_float); ++i) {
4698             if (!ast_global_codegen(parser->imm_float[i], ir, false)) {
4699                 con_out("failed to generate global %s\n", parser->imm_float[i]->name);
4700                 ir_builder_delete(ir);
4701                 return false;
4702             }
4703         }
4704         for (i = 0; i < vec_size(parser->imm_string); ++i) {
4705             if (!ast_global_codegen(parser->imm_string[i], ir, false)) {
4706                 con_out("failed to generate global %s\n", parser->imm_string[i]->name);
4707                 ir_builder_delete(ir);
4708                 return false;
4709             }
4710         }
4711         for (i = 0; i < vec_size(parser->imm_vector); ++i) {
4712             if (!ast_global_codegen(parser->imm_vector[i], ir, false)) {
4713                 con_out("failed to generate global %s\n", parser->imm_vector[i]->name);
4714                 ir_builder_delete(ir);
4715                 return false;
4716             }
4717         }
4718         for (i = 0; i < vec_size(parser->globals); ++i) {
4719             ast_value *asvalue;
4720             if (!ast_istype(parser->globals[i], ast_value))
4721                 continue;
4722             asvalue = (ast_value*)(parser->globals[i]);
4723             if (!ast_generate_accessors(asvalue, ir)) {
4724                 ir_builder_delete(ir);
4725                 return false;
4726             }
4727         }
4728         for (i = 0; i < vec_size(parser->fields); ++i) {
4729             ast_value *asvalue;
4730             asvalue = (ast_value*)(parser->fields[i]->expression.next);
4731
4732             if (!ast_istype((ast_expression*)asvalue, ast_value))
4733                 continue;
4734             if (asvalue->expression.vtype != TYPE_ARRAY)
4735                 continue;
4736             if (!ast_generate_accessors(asvalue, ir)) {
4737                 ir_builder_delete(ir);
4738                 return false;
4739             }
4740         }
4741         for (i = 0; i < vec_size(parser->functions); ++i) {
4742             if (!ast_function_codegen(parser->functions[i], ir)) {
4743                 con_out("failed to generate function %s\n", parser->functions[i]->name);
4744                 ir_builder_delete(ir);
4745                 return false;
4746             }
4747         }
4748         if (opts.dump)
4749             ir_builder_dump(ir, con_out);
4750         for (i = 0; i < vec_size(parser->functions); ++i) {
4751             if (!ir_function_finalize(parser->functions[i]->ir_func)) {
4752                 con_out("failed to finalize function %s\n", parser->functions[i]->name);
4753                 ir_builder_delete(ir);
4754                 return false;
4755             }
4756         }
4757
4758         if (retval) {
4759             if (opts.dumpfin)
4760                 ir_builder_dump(ir, con_out);
4761
4762             generate_checksum(parser);
4763
4764             if (!ir_builder_generate(ir, output)) {
4765                 con_out("*** failed to generate output file\n");
4766                 ir_builder_delete(ir);
4767                 return false;
4768             }
4769         }
4770
4771         ir_builder_delete(ir);
4772         return retval;
4773     }
4774
4775     con_out("*** there were compile errors\n");
4776     return false;
4777 }