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