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