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