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