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