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