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