Use the _t consistency naming scheme. Also various cleanups.
[xonotic/gmqcc.git] / parser.c
1 /*
2  * Copyright (C) 2012, 2013
3  *     Wolfgang Bumiller
4  *     Dale Weiler
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy of
7  * this software and associated documentation files (the "Software"), to deal in
8  * the Software without restriction, including without limitation the rights to
9  * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
10  * of the Software, and to permit persons to whom the Software is furnished to do
11  * so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in all
14  * copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22  * SOFTWARE.
23  */
24 #include <string.h>
25 #include <math.h>
26
27 #include "gmqcc.h"
28 #include "lexer.h"
29 #include "ast.h"
30
31 /* beginning of locals */
32 #define PARSER_HT_LOCALS  2
33
34 #define PARSER_HT_SIZE    512
35 #define TYPEDEF_HT_SIZE   512
36
37 typedef struct parser_s {
38     lex_file *lex;
39     int      tok;
40
41     bool     ast_cleaned;
42
43     ast_expression **globals;
44     ast_expression **fields;
45     ast_function **functions;
46     ast_value    **imm_float;
47     ast_value    **imm_string;
48     ast_value    **imm_vector;
49     size_t         translated;
50
51     ht ht_imm_string;
52     ht ht_imm_string_dotranslate;
53
54     /* must be deleted first, they reference immediates and values */
55     ast_value    **accessors;
56
57     ast_value *imm_float_zero;
58     ast_value *imm_float_one;
59     ast_value *imm_float_neg_one;
60
61     ast_value *imm_vector_zero;
62
63     ast_value *nil;
64     ast_value *reserved_version;
65
66     size_t crc_globals;
67     size_t crc_fields;
68
69     ast_function *function;
70     ht            aliases;
71
72     /* All the labels the function defined...
73      * Should they be in ast_function instead?
74      */
75     ast_label  **labels;
76     ast_goto   **gotos;
77     const char **breaks;
78     const char **continues;
79
80     /* A list of hashtables for each scope */
81     ht *variables;
82     ht htfields;
83     ht htglobals;
84     ht *typedefs;
85
86     /* same as above but for the spelling corrector */
87     correct_trie_t  **correct_variables;
88     size_t         ***correct_variables_score;  /* vector of vector of size_t* */
89
90     /* not to be used directly, we use the hash table */
91     ast_expression **_locals;
92     size_t          *_blocklocals;
93     ast_value      **_typedefs;
94     size_t          *_blocktypedefs;
95     lex_ctx_t         *_block_ctx;
96
97     /* we store the '=' operator info */
98     const oper_info *assign_op;
99
100     /* magic values */
101     ast_value *const_vec[3];
102
103     /* pragma flags */
104     bool noref;
105
106     /* collected information */
107     size_t     max_param_count;
108 } parser_t;
109
110 static ast_expression * const intrinsic_debug_typestring = (ast_expression*)0x1;
111
112 static void parser_enterblock(parser_t *parser);
113 static bool parser_leaveblock(parser_t *parser);
114 static void parser_addlocal(parser_t *parser, const char *name, ast_expression *e);
115 static void parser_addglobal(parser_t *parser, const char *name, ast_expression *e);
116 static bool parse_typedef(parser_t *parser);
117 static bool parse_variable(parser_t *parser, ast_block *localblock, bool nofields, int qualifier, ast_value *cached_typedef, bool noref, bool is_static, uint32_t qflags, char *vstring);
118 static ast_block* parse_block(parser_t *parser);
119 static bool parse_block_into(parser_t *parser, ast_block *block);
120 static bool parse_statement_or_block(parser_t *parser, ast_expression **out);
121 static bool parse_statement(parser_t *parser, ast_block *block, ast_expression **out, bool allow_cases);
122 static ast_expression* parse_expression_leave(parser_t *parser, bool stopatcomma, bool truthvalue, bool with_labels);
123 static ast_expression* parse_expression(parser_t *parser, bool stopatcomma, bool with_labels);
124 static ast_value* parser_create_array_setter_proto(parser_t *parser, ast_value *array, const char *funcname);
125 static ast_value* parser_create_array_getter_proto(parser_t *parser, ast_value *array, const ast_expression *elemtype, const char *funcname);
126 static ast_value *parse_typename(parser_t *parser, ast_value **storebase, ast_value *cached_typedef);
127
128 static void parseerror(parser_t *parser, const char *fmt, ...)
129 {
130     va_list ap;
131     va_start(ap, fmt);
132     vcompile_error(parser->lex->tok.ctx, fmt, ap);
133     va_end(ap);
134 }
135
136 /* returns true if it counts as an error */
137 static bool GMQCC_WARN parsewarning(parser_t *parser, int warntype, const char *fmt, ...)
138 {
139     bool    r;
140     va_list ap;
141     va_start(ap, fmt);
142     r = vcompile_warning(parser->lex->tok.ctx, warntype, fmt, ap);
143     va_end(ap);
144     return r;
145 }
146
147 /**********************************************************************
148  * some maths used for constant folding
149  */
150
151 vec3_t vec3_add(vec3_t a, vec3_t b)
152 {
153     vec3_t out;
154     out.x = a.x + b.x;
155     out.y = a.y + b.y;
156     out.z = a.z + b.z;
157     return out;
158 }
159
160 vec3_t vec3_sub(vec3_t a, vec3_t b)
161 {
162     vec3_t out;
163     out.x = a.x - b.x;
164     out.y = a.y - b.y;
165     out.z = a.z - b.z;
166     return out;
167 }
168
169 qcfloat_t vec3_mulvv(vec3_t a, vec3_t b)
170 {
171     return (a.x * b.x + a.y * b.y + a.z * b.z);
172 }
173
174 vec3_t vec3_mulvf(vec3_t a, float b)
175 {
176     vec3_t out;
177     out.x = a.x * b;
178     out.y = a.y * b;
179     out.z = a.z * b;
180     return out;
181 }
182
183 /**********************************************************************
184  * parsing
185  */
186
187 static bool parser_next(parser_t *parser)
188 {
189     /* lex_do kills the previous token */
190     parser->tok = lex_do(parser->lex);
191     if (parser->tok == TOKEN_EOF)
192         return true;
193     if (parser->tok >= TOKEN_ERROR) {
194         parseerror(parser, "lex error");
195         return false;
196     }
197     return true;
198 }
199
200 #define parser_tokval(p) ((p)->lex->tok.value)
201 #define parser_token(p)  (&((p)->lex->tok))
202 #define parser_ctx(p)    ((p)->lex->tok.ctx)
203
204 static ast_value* parser_const_float(parser_t *parser, double d)
205 {
206     size_t i;
207     ast_value *out;
208     lex_ctx_t ctx;
209     for (i = 0; i < vec_size(parser->imm_float); ++i) {
210         const double compare = parser->imm_float[i]->constval.vfloat;
211         if (memcmp((const void*)&compare, (const void *)&d, sizeof(double)) == 0)
212             return parser->imm_float[i];
213     }
214     if (parser->lex)
215         ctx = parser_ctx(parser);
216     else {
217         memset(&ctx, 0, sizeof(ctx));
218     }
219     out = ast_value_new(ctx, "#IMMEDIATE", TYPE_FLOAT);
220     out->cvq      = CV_CONST;
221     out->hasvalue = true;
222     out->isimm    = true;
223     out->constval.vfloat = d;
224     vec_push(parser->imm_float, out);
225     return out;
226 }
227
228 static ast_value* parser_const_float_0(parser_t *parser)
229 {
230     if (!parser->imm_float_zero)
231         parser->imm_float_zero = parser_const_float(parser, 0);
232     return parser->imm_float_zero;
233 }
234
235 static ast_value* parser_const_float_neg1(parser_t *parser) {
236     if (!parser->imm_float_neg_one)
237         parser->imm_float_neg_one = parser_const_float(parser, -1);
238     return parser->imm_float_neg_one;
239 }
240
241 static ast_value* parser_const_float_1(parser_t *parser)
242 {
243     if (!parser->imm_float_one)
244         parser->imm_float_one = parser_const_float(parser, 1);
245     return parser->imm_float_one;
246 }
247
248 static char *parser_strdup(const char *str)
249 {
250     if (str && !*str) {
251         /* actually dup empty strings */
252         char *out = (char*)mem_a(1);
253         *out = 0;
254         return out;
255     }
256     return util_strdup(str);
257 }
258
259 static ast_value* parser_const_string(parser_t *parser, const char *str, bool dotranslate)
260 {
261     ht ht_string = (dotranslate)
262         ? parser->ht_imm_string_dotranslate
263         : parser->ht_imm_string;
264
265     ast_value *out;
266     size_t     hash = util_hthash(ht_string, str);
267
268     if ((out = (ast_value*)util_htgeth(ht_string, str, hash)))
269         return out;
270     /*
271     for (i = 0; i < vec_size(parser->imm_string); ++i) {
272         if (!strcmp(parser->imm_string[i]->constval.vstring, str))
273             return parser->imm_string[i];
274     }
275     */
276     if (dotranslate) {
277         char name[32];
278         util_snprintf(name, sizeof(name), "dotranslate_%lu", (unsigned long)(parser->translated++));
279         out = ast_value_new(parser_ctx(parser), name, TYPE_STRING);
280         out->expression.flags |= AST_FLAG_INCLUDE_DEF;
281     } else
282         out = ast_value_new(parser_ctx(parser), "#IMMEDIATE", TYPE_STRING);
283
284     out->cvq      = CV_CONST;
285     out->hasvalue = true;
286     out->isimm    = true;
287     out->constval.vstring = parser_strdup(str);
288     vec_push(parser->imm_string, out);
289     util_htseth(ht_string, str, hash, out);
290
291     return out;
292 }
293
294 static ast_value* parser_const_vector(parser_t *parser, vec3_t v)
295 {
296     size_t i;
297     ast_value *out;
298     for (i = 0; i < vec_size(parser->imm_vector); ++i) {
299         if (!memcmp(&parser->imm_vector[i]->constval.vvec, &v, sizeof(v)))
300             return parser->imm_vector[i];
301     }
302     out = ast_value_new(parser_ctx(parser), "#IMMEDIATE", TYPE_VECTOR);
303     out->cvq      = CV_CONST;
304     out->hasvalue = true;
305     out->isimm    = true;
306     out->constval.vvec = v;
307     vec_push(parser->imm_vector, out);
308     return out;
309 }
310
311 static ast_value* parser_const_vector_f(parser_t *parser, float x, float y, float z)
312 {
313     vec3_t v;
314     v.x = x;
315     v.y = y;
316     v.z = z;
317     return parser_const_vector(parser, v);
318 }
319
320 static ast_value* parser_const_vector_0(parser_t *parser)
321 {
322     if (!parser->imm_vector_zero)
323         parser->imm_vector_zero = parser_const_vector_f(parser, 0, 0, 0);
324     return parser->imm_vector_zero;
325 }
326
327 static ast_expression* parser_find_field(parser_t *parser, const char *name)
328 {
329     return ( ast_expression*)util_htget(parser->htfields, name);
330 }
331
332 static ast_expression* parser_find_label(parser_t *parser, const char *name)
333 {
334     size_t i;
335     for(i = 0; i < vec_size(parser->labels); i++)
336         if (!strcmp(parser->labels[i]->name, name))
337             return (ast_expression*)parser->labels[i];
338     return NULL;
339 }
340
341 static ast_expression* parser_find_global(parser_t *parser, const char *name)
342 {
343     ast_expression *var = (ast_expression*)util_htget(parser->aliases, parser_tokval(parser));
344     if (var)
345         return var;
346     return (ast_expression*)util_htget(parser->htglobals, name);
347 }
348
349 static ast_expression* parser_find_param(parser_t *parser, const char *name)
350 {
351     size_t i;
352     ast_value *fun;
353     if (!parser->function)
354         return NULL;
355     fun = parser->function->vtype;
356     for (i = 0; i < vec_size(fun->expression.params); ++i) {
357         if (!strcmp(fun->expression.params[i]->name, name))
358             return (ast_expression*)(fun->expression.params[i]);
359     }
360     return NULL;
361 }
362
363 static ast_expression* parser_find_local(parser_t *parser, const char *name, size_t upto, bool *isparam)
364 {
365     size_t          i, hash;
366     ast_expression *e;
367
368     hash = util_hthash(parser->htglobals, name);
369
370     *isparam = false;
371     for (i = vec_size(parser->variables); i > upto;) {
372         --i;
373         if ( (e = (ast_expression*)util_htgeth(parser->variables[i], name, hash)) )
374             return e;
375     }
376     *isparam = true;
377     return parser_find_param(parser, name);
378 }
379
380 static ast_expression* parser_find_var(parser_t *parser, const char *name)
381 {
382     bool dummy;
383     ast_expression *v;
384     v         = parser_find_local(parser, name, 0, &dummy);
385     if (!v) v = parser_find_global(parser, name);
386     return v;
387 }
388
389 static ast_value* parser_find_typedef(parser_t *parser, const char *name, size_t upto)
390 {
391     size_t     i, hash;
392     ast_value *e;
393     hash = util_hthash(parser->typedefs[0], name);
394
395     for (i = vec_size(parser->typedefs); i > upto;) {
396         --i;
397         if ( (e = (ast_value*)util_htgeth(parser->typedefs[i], name, hash)) )
398             return e;
399     }
400     return NULL;
401 }
402
403 /* include intrinsics */
404 #include "intrin.h"
405
406 typedef struct
407 {
408     size_t etype; /* 0 = expression, others are operators */
409     bool            isparen;
410     size_t          off;
411     ast_expression *out;
412     ast_block      *block; /* for commas and function calls */
413     lex_ctx_t ctx;
414 } sy_elem;
415
416 enum {
417     PAREN_EXPR,
418     PAREN_FUNC,
419     PAREN_INDEX,
420     PAREN_TERNARY1,
421     PAREN_TERNARY2
422 };
423 typedef struct
424 {
425     sy_elem        *out;
426     sy_elem        *ops;
427     size_t         *argc;
428     unsigned int   *paren;
429 } shunt;
430
431 static sy_elem syexp(lex_ctx_t ctx, ast_expression *v) {
432     sy_elem e;
433     e.etype = 0;
434     e.off   = 0;
435     e.out   = v;
436     e.block = NULL;
437     e.ctx   = ctx;
438     e.isparen = false;
439     return e;
440 }
441
442 static sy_elem syblock(lex_ctx_t ctx, ast_block *v) {
443     sy_elem e;
444     e.etype = 0;
445     e.off   = 0;
446     e.out   = (ast_expression*)v;
447     e.block = v;
448     e.ctx   = ctx;
449     e.isparen = false;
450     return e;
451 }
452
453 static sy_elem syop(lex_ctx_t ctx, const oper_info *op) {
454     sy_elem e;
455     e.etype = 1 + (op - operators);
456     e.off   = 0;
457     e.out   = NULL;
458     e.block = NULL;
459     e.ctx   = ctx;
460     e.isparen = false;
461     return e;
462 }
463
464 static sy_elem syparen(lex_ctx_t ctx, size_t off) {
465     sy_elem e;
466     e.etype = 0;
467     e.off   = off;
468     e.out   = NULL;
469     e.block = NULL;
470     e.ctx   = ctx;
471     e.isparen = true;
472     return e;
473 }
474
475 /* With regular precedence rules, ent.foo[n] is the same as (ent.foo)[n],
476  * so we need to rotate it to become ent.(foo[n]).
477  */
478 static bool rotate_entfield_array_index_nodes(ast_expression **out)
479 {
480     ast_array_index *index, *oldindex;
481     ast_entfield    *entfield;
482
483     ast_value       *field;
484     ast_expression  *sub;
485     ast_expression  *entity;
486
487     lex_ctx_t ctx = ast_ctx(*out);
488
489     if (!ast_istype(*out, ast_array_index))
490         return false;
491     index = (ast_array_index*)*out;
492
493     if (!ast_istype(index->array, ast_entfield))
494         return false;
495     entfield = (ast_entfield*)index->array;
496
497     if (!ast_istype(entfield->field, ast_value))
498         return false;
499     field = (ast_value*)entfield->field;
500
501     sub    = index->index;
502     entity = entfield->entity;
503
504     oldindex = index;
505
506     index = ast_array_index_new(ctx, (ast_expression*)field, sub);
507     entfield = ast_entfield_new(ctx, entity, (ast_expression*)index);
508     *out = (ast_expression*)entfield;
509
510     oldindex->array = NULL;
511     oldindex->index = NULL;
512     ast_delete(oldindex);
513
514     return true;
515 }
516
517 static bool immediate_is_true(lex_ctx_t ctx, ast_value *v)
518 {
519     switch (v->expression.vtype) {
520         case TYPE_FLOAT:
521             return !!v->constval.vfloat;
522         case TYPE_INTEGER:
523             return !!v->constval.vint;
524         case TYPE_VECTOR:
525             if (OPTS_FLAG(CORRECT_LOGIC))
526                 return v->constval.vvec.x &&
527                        v->constval.vvec.y &&
528                        v->constval.vvec.z;
529             else
530                 return !!(v->constval.vvec.x);
531         case TYPE_STRING:
532             if (!v->constval.vstring)
533                 return false;
534             if (v->constval.vstring && OPTS_FLAG(TRUE_EMPTY_STRINGS))
535                 return true;
536             return !!v->constval.vstring[0];
537         default:
538             compile_error(ctx, "internal error: immediate_is_true on invalid type");
539             return !!v->constval.vfunc;
540     }
541 }
542
543 static bool parser_sy_apply_operator(parser_t *parser, shunt *sy)
544 {
545     const oper_info *op;
546     lex_ctx_t ctx;
547     ast_expression *out = NULL;
548     ast_expression *exprs[3];
549     ast_block      *blocks[3];
550     ast_value      *asvalue[3];
551     ast_binstore   *asbinstore;
552     size_t i, assignop, addop, subop;
553     qcint_t  generated_op = 0;
554
555     char ty1[1024];
556     char ty2[1024];
557
558     if (!vec_size(sy->ops)) {
559         parseerror(parser, "internal error: missing operator");
560         return false;
561     }
562
563     if (vec_last(sy->ops).isparen) {
564         parseerror(parser, "unmatched parenthesis");
565         return false;
566     }
567
568     op = &operators[vec_last(sy->ops).etype - 1];
569     ctx = vec_last(sy->ops).ctx;
570
571     if (vec_size(sy->out) < op->operands) {
572         compile_error(ctx, "internal error: not enough operands: %i (operator %s (%i))", vec_size(sy->out),
573                       op->op, (int)op->id);
574         return false;
575     }
576
577     vec_shrinkby(sy->ops, 1);
578
579     /* op(:?) has no input and no output */
580     if (!op->operands)
581         return true;
582
583     vec_shrinkby(sy->out, op->operands);
584     for (i = 0; i < op->operands; ++i) {
585         exprs[i]  = sy->out[vec_size(sy->out)+i].out;
586         blocks[i] = sy->out[vec_size(sy->out)+i].block;
587         asvalue[i] = (ast_value*)exprs[i];
588
589         if (exprs[i]->vtype == TYPE_NOEXPR &&
590             !(i != 0 && op->id == opid2('?',':')) &&
591             !(i == 1 && op->id == opid1('.')))
592         {
593             if (ast_istype(exprs[i], ast_label))
594                 compile_error(ast_ctx(exprs[i]), "expected expression, got an unknown identifier");
595             else
596                 compile_error(ast_ctx(exprs[i]), "not an expression");
597             (void)!compile_warning(ast_ctx(exprs[i]), WARN_DEBUG, "expression %u\n", (unsigned int)i);
598         }
599     }
600
601     if (blocks[0] && !vec_size(blocks[0]->exprs) && op->id != opid1(',')) {
602         compile_error(ctx, "internal error: operator cannot be applied on empty blocks");
603         return false;
604     }
605
606 #define NotSameType(T) \
607              (exprs[0]->vtype != exprs[1]->vtype || \
608               exprs[0]->vtype != T)
609 #define CanConstFold1(A) \
610              (ast_istype((A), ast_value) && ((ast_value*)(A))->hasvalue && (((ast_value*)(A))->cvq == CV_CONST) &&\
611               (A)->vtype != TYPE_FUNCTION)
612 #define CanConstFold(A, B) \
613              (CanConstFold1(A) && CanConstFold1(B))
614 #define ConstV(i) (asvalue[(i)]->constval.vvec)
615 #define ConstF(i) (asvalue[(i)]->constval.vfloat)
616 #define ConstS(i) (asvalue[(i)]->constval.vstring)
617     switch (op->id)
618     {
619         default:
620             compile_error(ctx, "internal error: unhandled operator: %s (%i)", op->op, (int)op->id);
621             return false;
622
623         case opid1('.'):
624             if (exprs[0]->vtype == TYPE_VECTOR &&
625                 exprs[1]->vtype == TYPE_NOEXPR)
626             {
627                 if      (exprs[1] == (ast_expression*)parser->const_vec[0])
628                     out = (ast_expression*)ast_member_new(ctx, exprs[0], 0, NULL);
629                 else if (exprs[1] == (ast_expression*)parser->const_vec[1])
630                     out = (ast_expression*)ast_member_new(ctx, exprs[0], 1, NULL);
631                 else if (exprs[1] == (ast_expression*)parser->const_vec[2])
632                     out = (ast_expression*)ast_member_new(ctx, exprs[0], 2, NULL);
633                 else {
634                     compile_error(ctx, "access to invalid vector component");
635                     return false;
636                 }
637             }
638             else if (exprs[0]->vtype == TYPE_ENTITY) {
639                 if (exprs[1]->vtype != TYPE_FIELD) {
640                     compile_error(ast_ctx(exprs[1]), "type error: right hand of member-operand should be an entity-field");
641                     return false;
642                 }
643                 out = (ast_expression*)ast_entfield_new(ctx, exprs[0], exprs[1]);
644             }
645             else if (exprs[0]->vtype == TYPE_VECTOR) {
646                 compile_error(ast_ctx(exprs[1]), "vectors cannot be accessed this way");
647                 return false;
648             }
649             else {
650                 compile_error(ast_ctx(exprs[1]), "type error: member-of operator on something that is not an entity or vector");
651                 return false;
652             }
653             break;
654
655         case opid1('['):
656             if (exprs[0]->vtype != TYPE_ARRAY &&
657                 !(exprs[0]->vtype == TYPE_FIELD &&
658                   exprs[0]->next->vtype == TYPE_ARRAY))
659             {
660                 ast_type_to_string(exprs[0], ty1, sizeof(ty1));
661                 compile_error(ast_ctx(exprs[0]), "cannot index value of type %s", ty1);
662                 return false;
663             }
664             if (exprs[1]->vtype != TYPE_FLOAT) {
665                 ast_type_to_string(exprs[0], ty1, sizeof(ty1));
666                 compile_error(ast_ctx(exprs[1]), "index must be of type float, not %s", ty1);
667                 return false;
668             }
669             out = (ast_expression*)ast_array_index_new(ctx, exprs[0], exprs[1]);
670             if (rotate_entfield_array_index_nodes(&out))
671             {
672 #if 0
673                 /* This is not broken in fteqcc anymore */
674                 if (OPTS_OPTION_U32(OPTION_STANDARD) != COMPILER_GMQCC) {
675                     /* this error doesn't need to make us bail out */
676                     (void)!parsewarning(parser, WARN_EXTENSIONS,
677                                         "accessing array-field members of an entity without parenthesis\n"
678                                         " -> this is an extension from -std=gmqcc");
679                 }
680 #endif
681             }
682             break;
683
684         case opid1(','):
685             if (vec_size(sy->paren) && vec_last(sy->paren) == PAREN_FUNC) {
686                 vec_push(sy->out, syexp(ctx, exprs[0]));
687                 vec_push(sy->out, syexp(ctx, exprs[1]));
688                 vec_last(sy->argc)++;
689                 return true;
690             }
691             if (blocks[0]) {
692                 if (!ast_block_add_expr(blocks[0], exprs[1]))
693                     return false;
694             } else {
695                 blocks[0] = ast_block_new(ctx);
696                 if (!ast_block_add_expr(blocks[0], exprs[0]) ||
697                     !ast_block_add_expr(blocks[0], exprs[1]))
698                 {
699                     return false;
700                 }
701             }
702             ast_block_set_type(blocks[0], exprs[1]);
703
704             vec_push(sy->out, syblock(ctx, blocks[0]));
705             return true;
706
707         case opid2('+','P'):
708             out = exprs[0];
709             break;
710         case opid2('-','P'):
711             switch (exprs[0]->vtype) {
712                 case TYPE_FLOAT:
713                     if (CanConstFold1(exprs[0]))
714                         out = (ast_expression*)parser_const_float(parser, -ConstF(0));
715                     else
716                         out = (ast_expression*)ast_binary_new(ctx, INSTR_SUB_F,
717                                                               (ast_expression*)parser_const_float_0(parser),
718                                                               exprs[0]);
719                     break;
720                 case TYPE_VECTOR:
721                     if (CanConstFold1(exprs[0]))
722                         out = (ast_expression*)parser_const_vector_f(parser,
723                             -ConstV(0).x, -ConstV(0).y, -ConstV(0).z);
724                     else
725                         out = (ast_expression*)ast_binary_new(ctx, INSTR_SUB_V,
726                                                               (ast_expression*)parser_const_vector_0(parser),
727                                                               exprs[0]);
728                     break;
729                 default:
730                 compile_error(ctx, "invalid types used in expression: cannot negate type %s",
731                               type_name[exprs[0]->vtype]);
732                 return false;
733             }
734             break;
735
736         case opid2('!','P'):
737             switch (exprs[0]->vtype) {
738                 case TYPE_FLOAT:
739                     if (CanConstFold1(exprs[0]))
740                         out = (ast_expression*)parser_const_float(parser, !ConstF(0));
741                     else
742                         out = (ast_expression*)ast_unary_new(ctx, INSTR_NOT_F, exprs[0]);
743                     break;
744                 case TYPE_VECTOR:
745                     if (CanConstFold1(exprs[0]))
746                         out = (ast_expression*)parser_const_float(parser,
747                             (!ConstV(0).x && !ConstV(0).y && !ConstV(0).z));
748                     else
749                         out = (ast_expression*)ast_unary_new(ctx, INSTR_NOT_V, exprs[0]);
750                     break;
751                 case TYPE_STRING:
752                     if (CanConstFold1(exprs[0])) {
753                         if (OPTS_FLAG(TRUE_EMPTY_STRINGS))
754                             out = (ast_expression*)parser_const_float(parser, !ConstS(0));
755                         else
756                             out = (ast_expression*)parser_const_float(parser, !ConstS(0) || !*ConstS(0));
757                     } else {
758                         if (OPTS_FLAG(TRUE_EMPTY_STRINGS))
759                             out = (ast_expression*)ast_unary_new(ctx, INSTR_NOT_F, exprs[0]);
760                         else
761                             out = (ast_expression*)ast_unary_new(ctx, INSTR_NOT_S, exprs[0]);
762                     }
763                     break;
764                 /* we don't constant-fold NOT for these types */
765                 case TYPE_ENTITY:
766                     out = (ast_expression*)ast_unary_new(ctx, INSTR_NOT_ENT, exprs[0]);
767                     break;
768                 case TYPE_FUNCTION:
769                     out = (ast_expression*)ast_unary_new(ctx, INSTR_NOT_FNC, exprs[0]);
770                     break;
771                 default:
772                 compile_error(ctx, "invalid types used in expression: cannot logically negate type %s",
773                               type_name[exprs[0]->vtype]);
774                 return false;
775             }
776             break;
777
778         case opid1('+'):
779             if (exprs[0]->vtype != exprs[1]->vtype ||
780                 (exprs[0]->vtype != TYPE_VECTOR && exprs[0]->vtype != TYPE_FLOAT) )
781             {
782                 compile_error(ctx, "invalid types used in expression: cannot add type %s and %s",
783                               type_name[exprs[0]->vtype],
784                               type_name[exprs[1]->vtype]);
785                 return false;
786             }
787             switch (exprs[0]->vtype) {
788                 case TYPE_FLOAT:
789                     if (CanConstFold(exprs[0], exprs[1]))
790                     {
791                         out = (ast_expression*)parser_const_float(parser, ConstF(0) + ConstF(1));
792                     }
793                     else
794                         out = (ast_expression*)ast_binary_new(ctx, INSTR_ADD_F, exprs[0], exprs[1]);
795                     break;
796                 case TYPE_VECTOR:
797                     if (CanConstFold(exprs[0], exprs[1]))
798                         out = (ast_expression*)parser_const_vector(parser, vec3_add(ConstV(0), ConstV(1)));
799                     else
800                         out = (ast_expression*)ast_binary_new(ctx, INSTR_ADD_V, exprs[0], exprs[1]);
801                     break;
802                 default:
803                     compile_error(ctx, "invalid types used in expression: cannot add type %s and %s",
804                                   type_name[exprs[0]->vtype],
805                                   type_name[exprs[1]->vtype]);
806                     return false;
807             };
808             break;
809         case opid1('-'):
810             if (exprs[0]->vtype != exprs[1]->vtype ||
811                 (exprs[0]->vtype != TYPE_VECTOR && exprs[0]->vtype != TYPE_FLOAT) )
812             {
813                 compile_error(ctx, "invalid types used in expression: cannot subtract type %s from %s",
814                               type_name[exprs[1]->vtype],
815                               type_name[exprs[0]->vtype]);
816                 return false;
817             }
818             switch (exprs[0]->vtype) {
819                 case TYPE_FLOAT:
820                     if (CanConstFold(exprs[0], exprs[1]))
821                         out = (ast_expression*)parser_const_float(parser, ConstF(0) - ConstF(1));
822                     else
823                         out = (ast_expression*)ast_binary_new(ctx, INSTR_SUB_F, exprs[0], exprs[1]);
824                     break;
825                 case TYPE_VECTOR:
826                     if (CanConstFold(exprs[0], exprs[1]))
827                         out = (ast_expression*)parser_const_vector(parser, vec3_sub(ConstV(0), ConstV(1)));
828                     else
829                         out = (ast_expression*)ast_binary_new(ctx, INSTR_SUB_V, exprs[0], exprs[1]);
830                     break;
831                 default:
832                     compile_error(ctx, "invalid types used in expression: cannot subtract type %s from %s",
833                                   type_name[exprs[1]->vtype],
834                                   type_name[exprs[0]->vtype]);
835                     return false;
836             };
837             break;
838         case opid1('*'):
839             if (exprs[0]->vtype != exprs[1]->vtype &&
840                 !(exprs[0]->vtype == TYPE_VECTOR &&
841                   exprs[1]->vtype == TYPE_FLOAT) &&
842                 !(exprs[1]->vtype == TYPE_VECTOR &&
843                   exprs[0]->vtype == TYPE_FLOAT)
844                 )
845             {
846                 compile_error(ctx, "invalid types used in expression: cannot multiply types %s and %s",
847                               type_name[exprs[1]->vtype],
848                               type_name[exprs[0]->vtype]);
849                 return false;
850             }
851             switch (exprs[0]->vtype) {
852                 case TYPE_FLOAT:
853                     if (exprs[1]->vtype == TYPE_VECTOR)
854                     {
855                         if (CanConstFold(exprs[0], exprs[1]))
856                             out = (ast_expression*)parser_const_vector(parser, vec3_mulvf(ConstV(1), ConstF(0)));
857                         else
858                             out = (ast_expression*)ast_binary_new(ctx, INSTR_MUL_FV, exprs[0], exprs[1]);
859                     }
860                     else
861                     {
862                         if (CanConstFold(exprs[0], exprs[1]))
863                             out = (ast_expression*)parser_const_float(parser, ConstF(0) * ConstF(1));
864                         else
865                             out = (ast_expression*)ast_binary_new(ctx, INSTR_MUL_F, exprs[0], exprs[1]);
866                     }
867                     break;
868                 case TYPE_VECTOR:
869                     if (exprs[1]->vtype == TYPE_FLOAT)
870                     {
871                         if (CanConstFold(exprs[0], exprs[1]))
872                             out = (ast_expression*)parser_const_vector(parser, vec3_mulvf(ConstV(0), ConstF(1)));
873                         else
874                             out = (ast_expression*)ast_binary_new(ctx, INSTR_MUL_VF, exprs[0], exprs[1]);
875                     }
876                     else
877                     {
878                         if (CanConstFold(exprs[0], exprs[1]))
879                             out = (ast_expression*)parser_const_float(parser, vec3_mulvv(ConstV(0), ConstV(1)));
880                         else if (OPTS_OPTIMIZATION(OPTIM_VECTOR_COMPONENTS) && CanConstFold1(exprs[0])) {
881                             vec3_t vec = ConstV(0);
882                             if (!vec.y && !vec.z) { /* 'n 0 0' * v */
883                                 ++opts_optimizationcount[OPTIM_VECTOR_COMPONENTS];
884                                 out = (ast_expression*)ast_member_new(ctx, exprs[1], 0, NULL);
885                                 out->node.keep = false;
886                                 ((ast_member*)out)->rvalue = true;
887                                 if (vec.x != 1)
888                                     out = (ast_expression*)ast_binary_new(ctx, INSTR_MUL_F, (ast_expression*)parser_const_float(parser, vec.x), out);
889                             }
890                             else if (!vec.x && !vec.z) { /* '0 n 0' * v */
891                                 ++opts_optimizationcount[OPTIM_VECTOR_COMPONENTS];
892                                 out = (ast_expression*)ast_member_new(ctx, exprs[1], 1, NULL);
893                                 out->node.keep = false;
894                                 ((ast_member*)out)->rvalue = true;
895                                 if (vec.y != 1)
896                                     out = (ast_expression*)ast_binary_new(ctx, INSTR_MUL_F, (ast_expression*)parser_const_float(parser, vec.y), out);
897                             }
898                             else if (!vec.x && !vec.y) { /* '0 n 0' * v */
899                                 ++opts_optimizationcount[OPTIM_VECTOR_COMPONENTS];
900                                 out = (ast_expression*)ast_member_new(ctx, exprs[1], 2, NULL);
901                                 out->node.keep = false;
902                                 ((ast_member*)out)->rvalue = true;
903                                 if (vec.z != 1)
904                                     out = (ast_expression*)ast_binary_new(ctx, INSTR_MUL_F, (ast_expression*)parser_const_float(parser, vec.z), out);
905                             }
906                             else
907                                 out = (ast_expression*)ast_binary_new(ctx, INSTR_MUL_V, exprs[0], exprs[1]);
908                         }
909                         else if (OPTS_OPTIMIZATION(OPTIM_VECTOR_COMPONENTS) && CanConstFold1(exprs[1])) {
910                             vec3_t vec = ConstV(1);
911                             if (!vec.y && !vec.z) { /* v * 'n 0 0' */
912                                 ++opts_optimizationcount[OPTIM_VECTOR_COMPONENTS];
913                                 out = (ast_expression*)ast_member_new(ctx, exprs[0], 0, NULL);
914                                 out->node.keep = false;
915                                 ((ast_member*)out)->rvalue = true;
916                                 if (vec.x != 1)
917                                     out = (ast_expression*)ast_binary_new(ctx, INSTR_MUL_F, out, (ast_expression*)parser_const_float(parser, vec.x));
918                             }
919                             else if (!vec.x && !vec.z) { /* v * '0 n 0' */
920                                 ++opts_optimizationcount[OPTIM_VECTOR_COMPONENTS];
921                                 out = (ast_expression*)ast_member_new(ctx, exprs[0], 1, NULL);
922                                 out->node.keep = false;
923                                 ((ast_member*)out)->rvalue = true;
924                                 if (vec.y != 1)
925                                     out = (ast_expression*)ast_binary_new(ctx, INSTR_MUL_F, out, (ast_expression*)parser_const_float(parser, vec.y));
926                             }
927                             else if (!vec.x && !vec.y) { /* v * '0 n 0' */
928                                 ++opts_optimizationcount[OPTIM_VECTOR_COMPONENTS];
929                                 out = (ast_expression*)ast_member_new(ctx, exprs[0], 2, NULL);
930                                 out->node.keep = false;
931                                 ((ast_member*)out)->rvalue = true;
932                                 if (vec.z != 1)
933                                     out = (ast_expression*)ast_binary_new(ctx, INSTR_MUL_F, out, (ast_expression*)parser_const_float(parser, vec.z));
934                             }
935                             else
936                                 out = (ast_expression*)ast_binary_new(ctx, INSTR_MUL_V, exprs[0], exprs[1]);
937                         }
938                         else
939                             out = (ast_expression*)ast_binary_new(ctx, INSTR_MUL_V, exprs[0], exprs[1]);
940                     }
941                     break;
942                 default:
943                     compile_error(ctx, "invalid types used in expression: cannot multiply types %s and %s",
944                                   type_name[exprs[1]->vtype],
945                                   type_name[exprs[0]->vtype]);
946                     return false;
947             };
948             break;
949         case opid1('/'):
950             if (exprs[1]->vtype != TYPE_FLOAT) {
951                 ast_type_to_string(exprs[0], ty1, sizeof(ty1));
952                 ast_type_to_string(exprs[1], ty2, sizeof(ty2));
953                 compile_error(ctx, "invalid types used in expression: cannot divide types %s and %s", ty1, ty2);
954                 return false;
955             }
956             if (exprs[0]->vtype == TYPE_FLOAT) {
957                 if (CanConstFold(exprs[0], exprs[1]))
958                     out = (ast_expression*)parser_const_float(parser, ConstF(0) / ConstF(1));
959                 else
960                     out = (ast_expression*)ast_binary_new(ctx, INSTR_DIV_F, exprs[0], exprs[1]);
961             }
962             else if (exprs[0]->vtype == TYPE_VECTOR) {
963                 if (CanConstFold(exprs[0], exprs[1]))
964                     out = (ast_expression*)parser_const_vector(parser, vec3_mulvf(ConstV(0), 1.0/ConstF(1)));
965                 else {
966                     if (CanConstFold1(exprs[1])) {
967                         out = (ast_expression*)parser_const_float(parser, 1.0 / ConstF(1));
968                     } else {
969                         out = (ast_expression*)ast_binary_new(ctx, INSTR_DIV_F,
970                                                               (ast_expression*)parser_const_float_1(parser),
971                                                               exprs[1]);
972                     }
973                     if (!out) {
974                         compile_error(ctx, "internal error: failed to generate division");
975                         return false;
976                     }
977                     out = (ast_expression*)ast_binary_new(ctx, INSTR_MUL_VF, exprs[0], out);
978                 }
979             }
980             else
981             {
982                 ast_type_to_string(exprs[0], ty1, sizeof(ty1));
983                 ast_type_to_string(exprs[1], ty2, sizeof(ty2));
984                 compile_error(ctx, "invalid types used in expression: cannot divide types %s and %s", ty1, ty2);
985                 return false;
986             }
987             break;
988
989         case opid1('%'):
990             if (NotSameType(TYPE_FLOAT)) {
991                 compile_error(ctx, "invalid types used in expression: cannot perform modulo operation between types %s and %s",
992                     type_name[exprs[0]->vtype],
993                     type_name[exprs[1]->vtype]);
994                 return false;
995             }
996             if (CanConstFold(exprs[0], exprs[1])) {
997                 out = (ast_expression*)parser_const_float(parser,
998                             (float)(((qcint_t)ConstF(0)) % ((qcint_t)ConstF(1))));
999             } else {
1000                 /* generate a call to __builtin_mod */
1001                 ast_expression *mod  = intrin_func(parser, "mod");
1002                 ast_call       *call = NULL;
1003                 if (!mod) return false; /* can return null for missing floor */
1004
1005                 call = ast_call_new(parser_ctx(parser), mod);
1006                 vec_push(call->params, exprs[0]);
1007                 vec_push(call->params, exprs[1]);
1008
1009                 out = (ast_expression*)call;
1010             }
1011             break;
1012
1013         case opid2('%','='):
1014             compile_error(ctx, "%= is unimplemented");
1015             return false;
1016
1017         case opid1('|'):
1018         case opid1('&'):
1019             if (NotSameType(TYPE_FLOAT)) {
1020                 compile_error(ctx, "invalid types used in expression: cannot perform bit operations between types %s and %s",
1021                               type_name[exprs[0]->vtype],
1022                               type_name[exprs[1]->vtype]);
1023                 return false;
1024             }
1025             if (CanConstFold(exprs[0], exprs[1]))
1026                 out = (ast_expression*)parser_const_float(parser,
1027                     (op->id == opid1('|') ? (float)( ((qcint_t)ConstF(0)) | ((qcint_t)ConstF(1)) ) :
1028                                             (float)( ((qcint_t)ConstF(0)) & ((qcint_t)ConstF(1)) ) ));
1029             else
1030                 out = (ast_expression*)ast_binary_new(ctx,
1031                     (op->id == opid1('|') ? INSTR_BITOR : INSTR_BITAND),
1032                     exprs[0], exprs[1]);
1033             break;
1034         case opid1('^'):
1035             /*
1036              * Okay lets designate what the hell is an acceptable use
1037              * of the ^ operator. In many vector processing units, XOR
1038              * is allowed to be used on vectors, but only if the first
1039              * operand is a vector, the second operand can be a float
1040              * or vector. It's never legal for the first operand to be
1041              * a float, and then the following operand to be a vector.
1042              * Further more, the only time it is legal to do XOR otherwise
1043              * is when both operand are floats. This nicely crafted if
1044              * statement catches them all.
1045              *
1046              * In the event that the first operand is a vector, two
1047              * possible situations can arise, thus, each element of
1048              * vector A (operand A) is exclusive-ORed with the corresponding
1049              * element of vector B (operand B), If B is scalar, the
1050              * scalar value is first replicated for each element.
1051              *
1052              * The QCVM itself lacks a BITXOR instruction. Thus emulating
1053              * the mathematics of it is required. The following equation
1054              * is used: (LHS | RHS) & ~(LHS & RHS). However, due to the
1055              * QCVM also lacking a BITNEG instruction, we need to emulate
1056              * ~FOO with -1 - FOO, the whole process becoming this nicely
1057              * crafted expression: (LHS | RHS) & (-1 - (LHS & RHS)).
1058              *
1059              * When A is not scalar, this process is repeated for all
1060              * components of vector A with the value in operand B,
1061              * only if operand B is scalar. When A is not scalar, and B
1062              * is also not scalar, this process is repeated for all
1063              * components of the vector A with the components of vector B.
1064              * Finally when A is scalar and B is scalar, this process is
1065              * simply used once for A and B being LHS and RHS respectfully.
1066              *
1067              * Yes the semantics are a bit strange (no pun intended).
1068              * But then again BITXOR is strange itself, consdering it's
1069              * commutative, assocative, and elements of the BITXOR operation
1070              * are their own inverse.
1071              */
1072             if ( !(exprs[0]->vtype == TYPE_FLOAT  && exprs[1]->vtype == TYPE_FLOAT) &&
1073                  !(exprs[0]->vtype == TYPE_VECTOR && exprs[1]->vtype == TYPE_FLOAT) &&
1074                  !(exprs[0]->vtype == TYPE_VECTOR && exprs[1]->vtype == TYPE_VECTOR))
1075             {
1076                 compile_error(ctx, "invalid types used in expression: cannot perform bit operations between types %s and %s",
1077                               type_name[exprs[0]->vtype],
1078                               type_name[exprs[1]->vtype]);
1079                 return false;
1080             }
1081
1082             /*
1083              * IF the first expression is float, the following will be too
1084              * since scalar ^ vector is not allowed.
1085              */
1086             if (exprs[0]->vtype == TYPE_FLOAT) {
1087                 if(CanConstFold(exprs[0], exprs[1])) {
1088                     out = (ast_expression*)parser_const_float(parser, (float)((qcint_t)(ConstF(0)) ^ ((qcint_t)(ConstF(1)))));
1089                 } else {
1090                     ast_binary *expr = ast_binary_new(
1091                         ctx,
1092                         INSTR_SUB_F,
1093                         (ast_expression*)parser_const_float_neg1(parser),
1094                         (ast_expression*)ast_binary_new(
1095                             ctx,
1096                             INSTR_BITAND,
1097                             exprs[0],
1098                             exprs[1]
1099                         )
1100                     );
1101                     expr->refs = AST_REF_NONE;
1102
1103                     out = (ast_expression*)
1104                         ast_binary_new(
1105                             ctx,
1106                             INSTR_BITAND,
1107                             (ast_expression*)ast_binary_new(
1108                                 ctx,
1109                                 INSTR_BITOR,
1110                                 exprs[0],
1111                                 exprs[1]
1112                             ),
1113                             (ast_expression*)expr
1114                         );
1115                 }
1116             } else {
1117                 /*
1118                  * The first is a vector: vector is allowed to xor with vector and
1119                  * with scalar, branch here for the second operand.
1120                  */
1121                 if (exprs[1]->vtype == TYPE_VECTOR) {
1122                     /*
1123                      * Xor all the values of the vector components against the
1124                      * vectors components in question.
1125                      */
1126                     if (CanConstFold(exprs[0], exprs[1])) {
1127                         out = (ast_expression*)parser_const_vector_f(
1128                             parser,
1129                             (float)(((qcint_t)(ConstV(0).x)) ^ ((qcint_t)(ConstV(1).x))),
1130                             (float)(((qcint_t)(ConstV(0).y)) ^ ((qcint_t)(ConstV(1).y))),
1131                             (float)(((qcint_t)(ConstV(0).z)) ^ ((qcint_t)(ConstV(1).z)))
1132                         );
1133                     } else {
1134                         compile_error(ast_ctx(exprs[0]), "Not Yet Implemented: bit-xor for vector against vector");
1135                         return false;
1136                     }
1137                 } else {
1138                     /*
1139                      * Xor all the values of the vector components against the
1140                      * scalar in question.
1141                      */
1142                     if (CanConstFold(exprs[0], exprs[1])) {
1143                         out = (ast_expression*)parser_const_vector_f(
1144                             parser,
1145                             (float)(((qcint_t)(ConstV(0).x)) ^ ((qcint_t)(ConstF(1)))),
1146                             (float)(((qcint_t)(ConstV(0).y)) ^ ((qcint_t)(ConstF(1)))),
1147                             (float)(((qcint_t)(ConstV(0).z)) ^ ((qcint_t)(ConstF(1))))
1148                         );
1149                     } else {
1150                         compile_error(ast_ctx(exprs[0]), "Not Yet Implemented: bit-xor for vector against float");
1151                         return false;
1152                     }
1153                 }
1154             }
1155
1156             break;
1157
1158         case opid2('<','<'):
1159         case opid2('>','>'):
1160             if (CanConstFold(exprs[0], exprs[1]) && ! NotSameType(TYPE_FLOAT)) {
1161                 if (op->id == opid2('<','<'))
1162                     out = (ast_expression*)parser_const_float(parser, (double)((unsigned int)(ConstF(0)) << (unsigned int)(ConstF(1))));
1163                 else
1164                     out = (ast_expression*)parser_const_float(parser, (double)((unsigned int)(ConstF(0)) >> (unsigned int)(ConstF(1))));
1165                 break;
1166             }
1167         case opid3('<','<','='):
1168         case opid3('>','>','='):
1169             compile_error(ast_ctx(exprs[0]), "Not Yet Implemented: bit-shifts");
1170             return false;
1171
1172         case opid2('|','|'):
1173             generated_op += 1; /* INSTR_OR */
1174         case opid2('&','&'):
1175             generated_op += INSTR_AND;
1176             if (CanConstFold(exprs[0], exprs[1]))
1177             {
1178                 if (OPTS_FLAG(PERL_LOGIC)) {
1179                     if (immediate_is_true(ctx, asvalue[0]))
1180                         out = exprs[1];
1181                 }
1182                 else
1183                     out = (ast_expression*)parser_const_float(parser,
1184                           ( (generated_op == INSTR_OR)
1185                             ? (immediate_is_true(ctx, asvalue[0]) || immediate_is_true(ctx, asvalue[1]))
1186                             : (immediate_is_true(ctx, asvalue[0]) && immediate_is_true(ctx, asvalue[1])) )
1187                           ? 1 : 0);
1188             }
1189             else
1190             {
1191                 if (OPTS_FLAG(PERL_LOGIC) && !ast_compare_type(exprs[0], exprs[1])) {
1192                     ast_type_to_string(exprs[0], ty1, sizeof(ty1));
1193                     ast_type_to_string(exprs[1], ty2, sizeof(ty2));
1194                     compile_error(ctx, "invalid types for logical operation with -fperl-logic: %s and %s", ty1, ty2);
1195                     return false;
1196                 }
1197                 for (i = 0; i < 2; ++i) {
1198                     if (OPTS_FLAG(CORRECT_LOGIC) && exprs[i]->vtype == TYPE_VECTOR) {
1199                         out = (ast_expression*)ast_unary_new(ctx, INSTR_NOT_V, exprs[i]);
1200                         if (!out) break;
1201                         out = (ast_expression*)ast_unary_new(ctx, INSTR_NOT_F, out);
1202                         if (!out) break;
1203                         exprs[i] = out; out = NULL;
1204                         if (OPTS_FLAG(PERL_LOGIC)) {
1205                             /* here we want to keep the right expressions' type */
1206                             break;
1207                         }
1208                     }
1209                     else if (OPTS_FLAG(FALSE_EMPTY_STRINGS) && exprs[i]->vtype == TYPE_STRING) {
1210                         out = (ast_expression*)ast_unary_new(ctx, INSTR_NOT_S, exprs[i]);
1211                         if (!out) break;
1212                         out = (ast_expression*)ast_unary_new(ctx, INSTR_NOT_F, out);
1213                         if (!out) break;
1214                         exprs[i] = out; out = NULL;
1215                         if (OPTS_FLAG(PERL_LOGIC)) {
1216                             /* here we want to keep the right expressions' type */
1217                             break;
1218                         }
1219                     }
1220                 }
1221                 out = (ast_expression*)ast_binary_new(ctx, generated_op, exprs[0], exprs[1]);
1222             }
1223             break;
1224
1225         case opid2('?',':'):
1226             if (vec_last(sy->paren) != PAREN_TERNARY2) {
1227                 compile_error(ctx, "mismatched parenthesis/ternary");
1228                 return false;
1229             }
1230             vec_pop(sy->paren);
1231             if (!ast_compare_type(exprs[1], exprs[2])) {
1232                 ast_type_to_string(exprs[1], ty1, sizeof(ty1));
1233                 ast_type_to_string(exprs[2], ty2, sizeof(ty2));
1234                 compile_error(ctx, "operands of ternary expression must have the same type, got %s and %s", ty1, ty2);
1235                 return false;
1236             }
1237             if (CanConstFold1(exprs[0]))
1238                 out = (immediate_is_true(ctx, asvalue[0]) ? exprs[1] : exprs[2]);
1239             else
1240                 out = (ast_expression*)ast_ternary_new(ctx, exprs[0], exprs[1], exprs[2]);
1241             break;
1242
1243         case opid2('*', '*'):
1244             if (NotSameType(TYPE_FLOAT)) {
1245                 ast_type_to_string(exprs[0], ty1, sizeof(ty1));
1246                 ast_type_to_string(exprs[1], ty2, sizeof(ty2));
1247                 compile_error(ctx, "invalid types used in exponentiation: %s and %s",
1248                     ty1, ty2);
1249
1250                 return false;
1251             }
1252
1253             if (CanConstFold(exprs[0], exprs[1])) {
1254                 out = (ast_expression*)parser_const_float(parser, powf(ConstF(0), ConstF(1)));
1255             } else {
1256                 ast_call *gencall = ast_call_new(parser_ctx(parser), intrin_func(parser, "pow"));
1257                 vec_push(gencall->params, exprs[0]);
1258                 vec_push(gencall->params, exprs[1]);
1259                 out = (ast_expression*)gencall;
1260             }
1261             break;
1262
1263         case opid3('<','=','>'): /* -1, 0, or 1 */
1264             if (NotSameType(TYPE_FLOAT)) {
1265                 ast_type_to_string(exprs[0], ty1, sizeof(ty1));
1266                 ast_type_to_string(exprs[1], ty2, sizeof(ty2));
1267                 compile_error(ctx, "invalid types used in comparision: %s and %s",
1268                     ty1, ty2);
1269
1270                 return false;
1271             }
1272
1273             if (CanConstFold(exprs[0], exprs[1])) {
1274                 if (ConstF(0) < ConstF(1))
1275                     out = (ast_expression*)parser_const_float_neg1(parser);
1276                 else if (ConstF(0) == ConstF(1))
1277                     out = (ast_expression*)parser_const_float_0(parser);
1278                 else if (ConstF(0) > ConstF(1))
1279                     out = (ast_expression*)parser_const_float_1(parser);
1280             } else {
1281                 ast_binary *eq = ast_binary_new(ctx, INSTR_EQ_F, exprs[0], exprs[1]);
1282
1283                 eq->refs = AST_REF_NONE;
1284
1285                     /* if (lt) { */
1286                 out = (ast_expression*)ast_ternary_new(ctx,
1287                         (ast_expression*)ast_binary_new(ctx, INSTR_LT, exprs[0], exprs[1]),
1288                         /* out = -1 */
1289                         (ast_expression*)parser_const_float_neg1(parser),
1290                     /* } else { */
1291                         /* if (eq) { */
1292                         (ast_expression*)ast_ternary_new(ctx, (ast_expression*)eq,
1293                             /* out = 0 */
1294                             (ast_expression*)parser_const_float_0(parser),
1295                         /* } else { */
1296                             /* out = 1 */
1297                             (ast_expression*)parser_const_float_1(parser)
1298                         /* } */
1299                         )
1300                     /* } */
1301                     );
1302
1303             }
1304             break;
1305
1306         case opid1('>'):
1307             generated_op += 1; /* INSTR_GT */
1308         case opid1('<'):
1309             generated_op += 1; /* INSTR_LT */
1310         case opid2('>', '='):
1311             generated_op += 1; /* INSTR_GE */
1312         case opid2('<', '='):
1313             generated_op += INSTR_LE;
1314             if (NotSameType(TYPE_FLOAT)) {
1315                 compile_error(ctx, "invalid types used in expression: cannot perform comparison between types %s and %s",
1316                               type_name[exprs[0]->vtype],
1317                               type_name[exprs[1]->vtype]);
1318                 return false;
1319             }
1320             out = (ast_expression*)ast_binary_new(ctx, generated_op, exprs[0], exprs[1]);
1321             break;
1322         case opid2('!', '='):
1323             if (exprs[0]->vtype != exprs[1]->vtype) {
1324                 compile_error(ctx, "invalid types used in expression: cannot perform comparison between types %s and %s",
1325                               type_name[exprs[0]->vtype],
1326                               type_name[exprs[1]->vtype]);
1327                 return false;
1328             }
1329             out = (ast_expression*)ast_binary_new(ctx, type_ne_instr[exprs[0]->vtype], exprs[0], exprs[1]);
1330             break;
1331         case opid2('=', '='):
1332             if (exprs[0]->vtype != exprs[1]->vtype) {
1333                 compile_error(ctx, "invalid types used in expression: cannot perform comparison between types %s and %s",
1334                               type_name[exprs[0]->vtype],
1335                               type_name[exprs[1]->vtype]);
1336                 return false;
1337             }
1338             out = (ast_expression*)ast_binary_new(ctx, type_eq_instr[exprs[0]->vtype], exprs[0], exprs[1]);
1339             break;
1340
1341         case opid1('='):
1342             if (ast_istype(exprs[0], ast_entfield)) {
1343                 ast_expression *field = ((ast_entfield*)exprs[0])->field;
1344                 if (OPTS_FLAG(ADJUST_VECTOR_FIELDS) &&
1345                     exprs[0]->vtype == TYPE_FIELD &&
1346                     exprs[0]->next->vtype == TYPE_VECTOR)
1347                 {
1348                     assignop = type_storep_instr[TYPE_VECTOR];
1349                 }
1350                 else
1351                     assignop = type_storep_instr[exprs[0]->vtype];
1352                 if (assignop == VINSTR_END || !ast_compare_type(field->next, exprs[1]))
1353                 {
1354                     ast_type_to_string(field->next, ty1, sizeof(ty1));
1355                     ast_type_to_string(exprs[1], ty2, sizeof(ty2));
1356                     if (OPTS_FLAG(ASSIGN_FUNCTION_TYPES) &&
1357                         field->next->vtype == TYPE_FUNCTION &&
1358                         exprs[1]->vtype == TYPE_FUNCTION)
1359                     {
1360                         (void)!compile_warning(ctx, WARN_ASSIGN_FUNCTION_TYPES,
1361                                                "invalid types in assignment: cannot assign %s to %s", ty2, ty1);
1362                     }
1363                     else
1364                         compile_error(ctx, "invalid types in assignment: cannot assign %s to %s", ty2, ty1);
1365                 }
1366             }
1367             else
1368             {
1369                 if (OPTS_FLAG(ADJUST_VECTOR_FIELDS) &&
1370                     exprs[0]->vtype == TYPE_FIELD &&
1371                     exprs[0]->next->vtype == TYPE_VECTOR)
1372                 {
1373                     assignop = type_store_instr[TYPE_VECTOR];
1374                 }
1375                 else {
1376                     assignop = type_store_instr[exprs[0]->vtype];
1377                 }
1378
1379                 if (assignop == VINSTR_END) {
1380                     ast_type_to_string(exprs[0], ty1, sizeof(ty1));
1381                     ast_type_to_string(exprs[1], ty2, sizeof(ty2));
1382                     compile_error(ctx, "invalid types in assignment: cannot assign %s to %s", ty2, ty1);
1383                 }
1384                 else if (!ast_compare_type(exprs[0], exprs[1]))
1385                 {
1386                     ast_type_to_string(exprs[0], ty1, sizeof(ty1));
1387                     ast_type_to_string(exprs[1], ty2, sizeof(ty2));
1388                     if (OPTS_FLAG(ASSIGN_FUNCTION_TYPES) &&
1389                         exprs[0]->vtype == TYPE_FUNCTION &&
1390                         exprs[1]->vtype == TYPE_FUNCTION)
1391                     {
1392                         (void)!compile_warning(ctx, WARN_ASSIGN_FUNCTION_TYPES,
1393                                                "invalid types in assignment: cannot assign %s to %s", ty2, ty1);
1394                     }
1395                     else
1396                         compile_error(ctx, "invalid types in assignment: cannot assign %s to %s", ty2, ty1);
1397                 }
1398             }
1399             if (ast_istype(exprs[0], ast_value) && asvalue[0]->cvq == CV_CONST) {
1400                 compile_error(ctx, "assignment to constant `%s`", asvalue[0]->name);
1401             }
1402             out = (ast_expression*)ast_store_new(ctx, assignop, exprs[0], exprs[1]);
1403             break;
1404         case opid3('+','+','P'):
1405         case opid3('-','-','P'):
1406             /* prefix ++ */
1407             if (exprs[0]->vtype != TYPE_FLOAT) {
1408                 ast_type_to_string(exprs[0], ty1, sizeof(ty1));
1409                 compile_error(ast_ctx(exprs[0]), "invalid type for prefix increment: %s", ty1);
1410                 return false;
1411             }
1412             if (op->id == opid3('+','+','P'))
1413                 addop = INSTR_ADD_F;
1414             else
1415                 addop = INSTR_SUB_F;
1416             if (ast_istype(exprs[0], ast_value) && asvalue[0]->cvq == CV_CONST) {
1417                 compile_error(ast_ctx(exprs[0]), "assignment to constant `%s`", asvalue[0]->name);
1418             }
1419             if (ast_istype(exprs[0], ast_entfield)) {
1420                 out = (ast_expression*)ast_binstore_new(ctx, INSTR_STOREP_F, addop,
1421                                                         exprs[0],
1422                                                         (ast_expression*)parser_const_float_1(parser));
1423             } else {
1424                 out = (ast_expression*)ast_binstore_new(ctx, INSTR_STORE_F, addop,
1425                                                         exprs[0],
1426                                                         (ast_expression*)parser_const_float_1(parser));
1427             }
1428             break;
1429         case opid3('S','+','+'):
1430         case opid3('S','-','-'):
1431             /* prefix ++ */
1432             if (exprs[0]->vtype != TYPE_FLOAT) {
1433                 ast_type_to_string(exprs[0], ty1, sizeof(ty1));
1434                 compile_error(ast_ctx(exprs[0]), "invalid type for suffix increment: %s", ty1);
1435                 return false;
1436             }
1437             if (op->id == opid3('S','+','+')) {
1438                 addop = INSTR_ADD_F;
1439                 subop = INSTR_SUB_F;
1440             } else {
1441                 addop = INSTR_SUB_F;
1442                 subop = INSTR_ADD_F;
1443             }
1444             if (ast_istype(exprs[0], ast_value) && asvalue[0]->cvq == CV_CONST) {
1445                 compile_error(ast_ctx(exprs[0]), "assignment to constant `%s`", asvalue[0]->name);
1446             }
1447             if (ast_istype(exprs[0], ast_entfield)) {
1448                 out = (ast_expression*)ast_binstore_new(ctx, INSTR_STOREP_F, addop,
1449                                                         exprs[0],
1450                                                         (ast_expression*)parser_const_float_1(parser));
1451             } else {
1452                 out = (ast_expression*)ast_binstore_new(ctx, INSTR_STORE_F, addop,
1453                                                         exprs[0],
1454                                                         (ast_expression*)parser_const_float_1(parser));
1455             }
1456             if (!out)
1457                 return false;
1458             out = (ast_expression*)ast_binary_new(ctx, subop,
1459                                                   out,
1460                                                   (ast_expression*)parser_const_float_1(parser));
1461             break;
1462         case opid2('+','='):
1463         case opid2('-','='):
1464             if (exprs[0]->vtype != exprs[1]->vtype ||
1465                 (exprs[0]->vtype != TYPE_VECTOR && exprs[0]->vtype != TYPE_FLOAT) )
1466             {
1467                 ast_type_to_string(exprs[0], ty1, sizeof(ty1));
1468                 ast_type_to_string(exprs[1], ty2, sizeof(ty2));
1469                 compile_error(ctx, "invalid types used in expression: cannot add or subtract type %s and %s",
1470                               ty1, ty2);
1471                 return false;
1472             }
1473             if (ast_istype(exprs[0], ast_value) && asvalue[0]->cvq == CV_CONST) {
1474                 compile_error(ctx, "assignment to constant `%s`", asvalue[0]->name);
1475             }
1476             if (ast_istype(exprs[0], ast_entfield))
1477                 assignop = type_storep_instr[exprs[0]->vtype];
1478             else
1479                 assignop = type_store_instr[exprs[0]->vtype];
1480             switch (exprs[0]->vtype) {
1481                 case TYPE_FLOAT:
1482                     out = (ast_expression*)ast_binstore_new(ctx, assignop,
1483                                                             (op->id == opid2('+','=') ? INSTR_ADD_F : INSTR_SUB_F),
1484                                                             exprs[0], exprs[1]);
1485                     break;
1486                 case TYPE_VECTOR:
1487                     out = (ast_expression*)ast_binstore_new(ctx, assignop,
1488                                                             (op->id == opid2('+','=') ? INSTR_ADD_V : INSTR_SUB_V),
1489                                                             exprs[0], exprs[1]);
1490                     break;
1491                 default:
1492                     compile_error(ctx, "invalid types used in expression: cannot add or subtract type %s and %s",
1493                                   type_name[exprs[0]->vtype],
1494                                   type_name[exprs[1]->vtype]);
1495                     return false;
1496             };
1497             break;
1498         case opid2('*','='):
1499         case opid2('/','='):
1500             if (exprs[1]->vtype != TYPE_FLOAT ||
1501                 !(exprs[0]->vtype == TYPE_FLOAT ||
1502                   exprs[0]->vtype == TYPE_VECTOR))
1503             {
1504                 ast_type_to_string(exprs[0], ty1, sizeof(ty1));
1505                 ast_type_to_string(exprs[1], ty2, sizeof(ty2));
1506                 compile_error(ctx, "invalid types used in expression: %s and %s",
1507                               ty1, ty2);
1508                 return false;
1509             }
1510             if (ast_istype(exprs[0], ast_value) && asvalue[0]->cvq == CV_CONST) {
1511                 compile_error(ctx, "assignment to constant `%s`", asvalue[0]->name);
1512             }
1513             if (ast_istype(exprs[0], ast_entfield))
1514                 assignop = type_storep_instr[exprs[0]->vtype];
1515             else
1516                 assignop = type_store_instr[exprs[0]->vtype];
1517             switch (exprs[0]->vtype) {
1518                 case TYPE_FLOAT:
1519                     out = (ast_expression*)ast_binstore_new(ctx, assignop,
1520                                                             (op->id == opid2('*','=') ? INSTR_MUL_F : INSTR_DIV_F),
1521                                                             exprs[0], exprs[1]);
1522                     break;
1523                 case TYPE_VECTOR:
1524                     if (op->id == opid2('*','=')) {
1525                         out = (ast_expression*)ast_binstore_new(ctx, assignop, INSTR_MUL_VF,
1526                                                                 exprs[0], exprs[1]);
1527                     } else {
1528                         /* there's no DIV_VF */
1529                         if (CanConstFold1(exprs[1])) {
1530                             out = (ast_expression*)parser_const_float(parser, 1.0 / ConstF(1));
1531                         } else {
1532                             out = (ast_expression*)ast_binary_new(ctx, INSTR_DIV_F,
1533                                                                   (ast_expression*)parser_const_float_1(parser),
1534                                                                   exprs[1]);
1535                         }
1536                         if (!out) {
1537                             compile_error(ctx, "internal error: failed to generate division");
1538                             return false;
1539                         }
1540                         out = (ast_expression*)ast_binstore_new(ctx, assignop, INSTR_MUL_VF,
1541                                                                 exprs[0], out);
1542                     }
1543                     break;
1544                 default:
1545                     compile_error(ctx, "invalid types used in expression: cannot add or subtract type %s and %s",
1546                                   type_name[exprs[0]->vtype],
1547                                   type_name[exprs[1]->vtype]);
1548                     return false;
1549             };
1550             break;
1551         case opid2('&','='):
1552         case opid2('|','='):
1553             if (NotSameType(TYPE_FLOAT)) {
1554                 ast_type_to_string(exprs[0], ty1, sizeof(ty1));
1555                 ast_type_to_string(exprs[1], ty2, sizeof(ty2));
1556                 compile_error(ctx, "invalid types used in expression: %s and %s",
1557                               ty1, ty2);
1558                 return false;
1559             }
1560             if (ast_istype(exprs[0], ast_value) && asvalue[0]->cvq == CV_CONST) {
1561                 compile_error(ctx, "assignment to constant `%s`", asvalue[0]->name);
1562             }
1563             if (ast_istype(exprs[0], ast_entfield))
1564                 assignop = type_storep_instr[exprs[0]->vtype];
1565             else
1566                 assignop = type_store_instr[exprs[0]->vtype];
1567             out = (ast_expression*)ast_binstore_new(ctx, assignop,
1568                                                     (op->id == opid2('&','=') ? INSTR_BITAND : INSTR_BITOR),
1569                                                     exprs[0], exprs[1]);
1570             break;
1571         case opid3('&','~','='):
1572             /* This is like: a &= ~(b);
1573              * But QC has no bitwise-not, so we implement it as
1574              * a -= a & (b);
1575              */
1576             if (NotSameType(TYPE_FLOAT)) {
1577                 ast_type_to_string(exprs[0], ty1, sizeof(ty1));
1578                 ast_type_to_string(exprs[1], ty2, sizeof(ty2));
1579                 compile_error(ctx, "invalid types used in expression: %s and %s",
1580                               ty1, ty2);
1581                 return false;
1582             }
1583             if (ast_istype(exprs[0], ast_entfield))
1584                 assignop = type_storep_instr[exprs[0]->vtype];
1585             else
1586                 assignop = type_store_instr[exprs[0]->vtype];
1587             out = (ast_expression*)ast_binary_new(ctx, INSTR_BITAND, exprs[0], exprs[1]);
1588             if (!out)
1589                 return false;
1590             if (ast_istype(exprs[0], ast_value) && asvalue[0]->cvq == CV_CONST) {
1591                 compile_error(ctx, "assignment to constant `%s`", asvalue[0]->name);
1592             }
1593             asbinstore = ast_binstore_new(ctx, assignop, INSTR_SUB_F, exprs[0], out);
1594             asbinstore->keep_dest = true;
1595             out = (ast_expression*)asbinstore;
1596             break;
1597
1598         case opid2('~', 'P'):
1599             if (exprs[0]->vtype != TYPE_FLOAT) {
1600                 ast_type_to_string(exprs[0], ty1, sizeof(ty1));
1601                 compile_error(ast_ctx(exprs[0]), "invalid type for bit not: %s", ty1);
1602                 return false;
1603             }
1604
1605             if(CanConstFold1(exprs[0]))
1606                 out = (ast_expression*)parser_const_float(parser, ~(qcint_t)ConstF(0));
1607             else
1608                 out = (ast_expression*)
1609                     ast_binary_new(ctx, INSTR_SUB_F, (ast_expression*)parser_const_float_neg1(parser), exprs[0]);
1610             break;
1611     }
1612 #undef NotSameType
1613
1614     if (!out) {
1615         compile_error(ctx, "failed to apply operator %s", op->op);
1616         return false;
1617     }
1618
1619     vec_push(sy->out, syexp(ctx, out));
1620     return true;
1621 }
1622
1623 static bool parser_close_call(parser_t *parser, shunt *sy)
1624 {
1625     /* was a function call */
1626     ast_expression *fun;
1627     ast_value      *funval = NULL;
1628     ast_call       *call;
1629
1630     size_t          fid;
1631     size_t          paramcount, i;
1632
1633     fid = vec_last(sy->ops).off;
1634     vec_shrinkby(sy->ops, 1);
1635
1636     /* out[fid] is the function
1637      * everything above is parameters...
1638      */
1639     if (!vec_size(sy->argc)) {
1640         parseerror(parser, "internal error: no argument counter available");
1641         return false;
1642     }
1643
1644     paramcount = vec_last(sy->argc);
1645     vec_pop(sy->argc);
1646
1647     if (vec_size(sy->out) < fid) {
1648         parseerror(parser, "internal error: broken function call%lu < %lu+%lu\n",
1649                    (unsigned long)vec_size(sy->out),
1650                    (unsigned long)fid,
1651                    (unsigned long)paramcount);
1652         return false;
1653     }
1654
1655     fun = sy->out[fid].out;
1656
1657     if (fun == intrinsic_debug_typestring) {
1658         char ty[1024];
1659         if (fid+2 != vec_size(sy->out) ||
1660             vec_last(sy->out).block)
1661         {
1662             parseerror(parser, "intrinsic __builtin_debug_typestring requires exactly 1 parameter");
1663             return false;
1664         }
1665         ast_type_to_string(vec_last(sy->out).out, ty, sizeof(ty));
1666         ast_unref(vec_last(sy->out).out);
1667         sy->out[fid] = syexp(ast_ctx(vec_last(sy->out).out),
1668                              (ast_expression*)parser_const_string(parser, ty, false));
1669         vec_shrinkby(sy->out, 1);
1670         return true;
1671     }
1672
1673     call = ast_call_new(sy->ops[vec_size(sy->ops)].ctx, fun);
1674     if (!call)
1675         return false;
1676
1677     if (fid+1 < vec_size(sy->out))
1678         ++paramcount;
1679
1680     if (fid+1 + paramcount != vec_size(sy->out)) {
1681         parseerror(parser, "internal error: parameter count mismatch: (%lu+1+%lu), %lu",
1682                    (unsigned long)fid, (unsigned long)paramcount, (unsigned long)vec_size(sy->out));
1683         return false;
1684     }
1685
1686     for (i = 0; i < paramcount; ++i)
1687         vec_push(call->params, sy->out[fid+1 + i].out);
1688     vec_shrinkby(sy->out, paramcount);
1689     (void)!ast_call_check_types(call, parser->function->vtype->expression.varparam);
1690     if (parser->max_param_count < paramcount)
1691         parser->max_param_count = paramcount;
1692
1693     if (ast_istype(fun, ast_value)) {
1694         funval = (ast_value*)fun;
1695         if ((fun->flags & AST_FLAG_VARIADIC) &&
1696             !(/*funval->cvq == CV_CONST && */ funval->hasvalue && funval->constval.vfunc->builtin))
1697         {
1698             call->va_count = (ast_expression*)parser_const_float(parser, (double)paramcount);
1699         }
1700     }
1701
1702     /* overwrite fid, the function, with a call */
1703     sy->out[fid] = syexp(call->expression.node.context, (ast_expression*)call);
1704
1705     if (fun->vtype != TYPE_FUNCTION) {
1706         parseerror(parser, "not a function (%s)", type_name[fun->vtype]);
1707         return false;
1708     }
1709
1710     if (!fun->next) {
1711         parseerror(parser, "could not determine function return type");
1712         return false;
1713     } else {
1714         ast_value *fval = (ast_istype(fun, ast_value) ? ((ast_value*)fun) : NULL);
1715
1716         if (fun->flags & AST_FLAG_DEPRECATED) {
1717             if (!fval) {
1718                 return !parsewarning(parser, WARN_DEPRECATED,
1719                         "call to function (which is marked deprecated)\n",
1720                         "-> it has been declared here: %s:%i",
1721                         ast_ctx(fun).file, ast_ctx(fun).line);
1722             }
1723             if (!fval->desc) {
1724                 return !parsewarning(parser, WARN_DEPRECATED,
1725                         "call to `%s` (which is marked deprecated)\n"
1726                         "-> `%s` declared here: %s:%i",
1727                         fval->name, fval->name, ast_ctx(fun).file, ast_ctx(fun).line);
1728             }
1729             return !parsewarning(parser, WARN_DEPRECATED,
1730                     "call to `%s` (deprecated: %s)\n"
1731                     "-> `%s` declared here: %s:%i",
1732                     fval->name, fval->desc, fval->name, ast_ctx(fun).file,
1733                     ast_ctx(fun).line);
1734         }
1735
1736         if (vec_size(fun->params) != paramcount &&
1737             !((fun->flags & AST_FLAG_VARIADIC) &&
1738               vec_size(fun->params) < paramcount))
1739         {
1740             const char *fewmany = (vec_size(fun->params) > paramcount) ? "few" : "many";
1741             if (fval)
1742                 return !parsewarning(parser, WARN_INVALID_PARAMETER_COUNT,
1743                                      "too %s parameters for call to %s: expected %i, got %i\n"
1744                                      " -> `%s` has been declared here: %s:%i",
1745                                      fewmany, fval->name, (int)vec_size(fun->params), (int)paramcount,
1746                                      fval->name, ast_ctx(fun).file, (int)ast_ctx(fun).line);
1747             else
1748                 return !parsewarning(parser, WARN_INVALID_PARAMETER_COUNT,
1749                                      "too %s parameters for function call: expected %i, got %i\n"
1750                                      " -> it has been declared here: %s:%i",
1751                                      fewmany, (int)vec_size(fun->params), (int)paramcount,
1752                                      ast_ctx(fun).file, (int)ast_ctx(fun).line);
1753         }
1754     }
1755
1756     return true;
1757 }
1758
1759 static bool parser_close_paren(parser_t *parser, shunt *sy)
1760 {
1761     if (!vec_size(sy->ops)) {
1762         parseerror(parser, "unmatched closing paren");
1763         return false;
1764     }
1765
1766     while (vec_size(sy->ops)) {
1767         if (vec_last(sy->ops).isparen) {
1768             if (vec_last(sy->paren) == PAREN_FUNC) {
1769                 vec_pop(sy->paren);
1770                 if (!parser_close_call(parser, sy))
1771                     return false;
1772                 break;
1773             }
1774             if (vec_last(sy->paren) == PAREN_EXPR) {
1775                 vec_pop(sy->paren);
1776                 if (!vec_size(sy->out)) {
1777                     compile_error(vec_last(sy->ops).ctx, "empty paren expression");
1778                     vec_shrinkby(sy->ops, 1);
1779                     return false;
1780                 }
1781                 vec_shrinkby(sy->ops, 1);
1782                 break;
1783             }
1784             if (vec_last(sy->paren) == PAREN_INDEX) {
1785                 vec_pop(sy->paren);
1786                 /* pop off the parenthesis */
1787                 vec_shrinkby(sy->ops, 1);
1788                 /* then apply the index operator */
1789                 if (!parser_sy_apply_operator(parser, sy))
1790                     return false;
1791                 break;
1792             }
1793             if (vec_last(sy->paren) == PAREN_TERNARY1) {
1794                 vec_last(sy->paren) = PAREN_TERNARY2;
1795                 /* pop off the parenthesis */
1796                 vec_shrinkby(sy->ops, 1);
1797                 break;
1798             }
1799             compile_error(vec_last(sy->ops).ctx, "invalid parenthesis");
1800             return false;
1801         }
1802         if (!parser_sy_apply_operator(parser, sy))
1803             return false;
1804     }
1805     return true;
1806 }
1807
1808 static void parser_reclassify_token(parser_t *parser)
1809 {
1810     size_t i;
1811     if (parser->tok >= TOKEN_START)
1812         return;
1813     for (i = 0; i < operator_count; ++i) {
1814         if (!strcmp(parser_tokval(parser), operators[i].op)) {
1815             parser->tok = TOKEN_OPERATOR;
1816             return;
1817         }
1818     }
1819 }
1820
1821 static ast_expression* parse_vararg_do(parser_t *parser)
1822 {
1823     ast_expression *idx, *out;
1824     ast_value      *typevar;
1825     ast_value      *funtype = parser->function->vtype;
1826     lex_ctx_t         ctx     = parser_ctx(parser);
1827
1828     if (!parser->function->varargs) {
1829         parseerror(parser, "function has no variable argument list");
1830         return NULL;
1831     }
1832
1833     if (!parser_next(parser) || parser->tok != '(') {
1834         parseerror(parser, "expected parameter index and type in parenthesis");
1835         return NULL;
1836     }
1837     if (!parser_next(parser)) {
1838         parseerror(parser, "error parsing parameter index");
1839         return NULL;
1840     }
1841
1842     idx = parse_expression_leave(parser, true, false, false);
1843     if (!idx)
1844         return NULL;
1845
1846     if (parser->tok != ',') {
1847         if (parser->tok != ')') {
1848             ast_unref(idx);
1849             parseerror(parser, "expected comma after parameter index");
1850             return NULL;
1851         }
1852         /* vararg piping: ...(start) */
1853         out = (ast_expression*)ast_argpipe_new(ctx, idx);
1854         return out;
1855     }
1856
1857     if (!parser_next(parser) || (parser->tok != TOKEN_IDENT && parser->tok != TOKEN_TYPENAME)) {
1858         ast_unref(idx);
1859         parseerror(parser, "expected typename for vararg");
1860         return NULL;
1861     }
1862
1863     typevar = parse_typename(parser, NULL, NULL);
1864     if (!typevar) {
1865         ast_unref(idx);
1866         return NULL;
1867     }
1868
1869     if (parser->tok != ')') {
1870         ast_unref(idx);
1871         ast_delete(typevar);
1872         parseerror(parser, "expected closing paren");
1873         return NULL;
1874     }
1875
1876     if (funtype->expression.varparam &&
1877         !ast_compare_type((ast_expression*)typevar, (ast_expression*)funtype->expression.varparam))
1878     {
1879         char ty1[1024];
1880         char ty2[1024];
1881         ast_type_to_string((ast_expression*)typevar, ty1, sizeof(ty1));
1882         ast_type_to_string((ast_expression*)funtype->expression.varparam, ty2, sizeof(ty2));
1883         compile_error(ast_ctx(typevar),
1884                       "function was declared to take varargs of type `%s`, requested type is: %s",
1885                       ty2, ty1);
1886     }
1887
1888     out = (ast_expression*)ast_array_index_new(ctx, (ast_expression*)(parser->function->varargs), idx);
1889     ast_type_adopt(out, typevar);
1890     ast_delete(typevar);
1891     return out;
1892 }
1893
1894 static ast_expression* parse_vararg(parser_t *parser)
1895 {
1896     bool           old_noops = parser->lex->flags.noops;
1897
1898     ast_expression *out;
1899
1900     parser->lex->flags.noops = true;
1901     out = parse_vararg_do(parser);
1902
1903     parser->lex->flags.noops = old_noops;
1904     return out;
1905 }
1906
1907 /* not to be exposed */
1908 extern bool ftepp_predef_exists(const char *name);
1909
1910 static bool parse_sya_operand(parser_t *parser, shunt *sy, bool with_labels)
1911 {
1912     if (OPTS_FLAG(TRANSLATABLE_STRINGS) &&
1913         parser->tok == TOKEN_IDENT &&
1914         !strcmp(parser_tokval(parser), "_"))
1915     {
1916         /* a translatable string */
1917         ast_value *val;
1918
1919         parser->lex->flags.noops = true;
1920         if (!parser_next(parser) || parser->tok != '(') {
1921             parseerror(parser, "use _(\"string\") to create a translatable string constant");
1922             return false;
1923         }
1924         parser->lex->flags.noops = false;
1925         if (!parser_next(parser) || parser->tok != TOKEN_STRINGCONST) {
1926             parseerror(parser, "expected a constant string in translatable-string extension");
1927             return false;
1928         }
1929         val = parser_const_string(parser, parser_tokval(parser), true);
1930         if (!val)
1931             return false;
1932         vec_push(sy->out, syexp(parser_ctx(parser), (ast_expression*)val));
1933
1934         if (!parser_next(parser) || parser->tok != ')') {
1935             parseerror(parser, "expected closing paren after translatable string");
1936             return false;
1937         }
1938         return true;
1939     }
1940     else if (parser->tok == TOKEN_DOTS)
1941     {
1942         ast_expression *va;
1943         if (!OPTS_FLAG(VARIADIC_ARGS)) {
1944             parseerror(parser, "cannot access varargs (try -fvariadic-args)");
1945             return false;
1946         }
1947         va = parse_vararg(parser);
1948         if (!va)
1949             return false;
1950         vec_push(sy->out, syexp(parser_ctx(parser), va));
1951         return true;
1952     }
1953     else if (parser->tok == TOKEN_FLOATCONST) {
1954         ast_value *val;
1955         val = parser_const_float(parser, (parser_token(parser)->constval.f));
1956         if (!val)
1957             return false;
1958         vec_push(sy->out, syexp(parser_ctx(parser), (ast_expression*)val));
1959         return true;
1960     }
1961     else if (parser->tok == TOKEN_INTCONST || parser->tok == TOKEN_CHARCONST) {
1962         ast_value *val;
1963         val = parser_const_float(parser, (double)(parser_token(parser)->constval.i));
1964         if (!val)
1965             return false;
1966         vec_push(sy->out, syexp(parser_ctx(parser), (ast_expression*)val));
1967         return true;
1968     }
1969     else if (parser->tok == TOKEN_STRINGCONST) {
1970         ast_value *val;
1971         val = parser_const_string(parser, parser_tokval(parser), false);
1972         if (!val)
1973             return false;
1974         vec_push(sy->out, syexp(parser_ctx(parser), (ast_expression*)val));
1975         return true;
1976     }
1977     else if (parser->tok == TOKEN_VECTORCONST) {
1978         ast_value *val;
1979         val = parser_const_vector(parser, parser_token(parser)->constval.v);
1980         if (!val)
1981             return false;
1982         vec_push(sy->out, syexp(parser_ctx(parser), (ast_expression*)val));
1983         return true;
1984     }
1985     else if (parser->tok == TOKEN_IDENT)
1986     {
1987         const char     *ctoken = parser_tokval(parser);
1988         ast_expression *prev = vec_size(sy->out) ? vec_last(sy->out).out : NULL;
1989         ast_expression *var;
1990         /* a_vector.{x,y,z} */
1991         if (!vec_size(sy->ops) ||
1992             !vec_last(sy->ops).etype ||
1993             operators[vec_last(sy->ops).etype-1].id != opid1('.') ||
1994             (prev >= intrinsic_debug_typestring &&
1995              prev <= intrinsic_debug_typestring))
1996         {
1997             /* When adding more intrinsics, fix the above condition */
1998             prev = NULL;
1999         }
2000         if (prev && prev->vtype == TYPE_VECTOR && ctoken[0] >= 'x' && ctoken[0] <= 'z' && !ctoken[1])
2001         {
2002             var = (ast_expression*)parser->const_vec[ctoken[0]-'x'];
2003         } else {
2004             var = parser_find_var(parser, parser_tokval(parser));
2005             if (!var)
2006                 var = parser_find_field(parser, parser_tokval(parser));
2007         }
2008         if (!var && with_labels) {
2009             var = (ast_expression*)parser_find_label(parser, parser_tokval(parser));
2010             if (!with_labels) {
2011                 ast_label *lbl = ast_label_new(parser_ctx(parser), parser_tokval(parser), true);
2012                 var = (ast_expression*)lbl;
2013                 vec_push(parser->labels, lbl);
2014             }
2015         }
2016         if (!var && !strcmp(parser_tokval(parser), "__FUNC__"))
2017             var = (ast_expression*)parser_const_string(parser, parser->function->name, false);
2018         if (!var) {
2019             /* intrinsics */
2020             if (!strcmp(parser_tokval(parser), "__builtin_debug_typestring")) {
2021                 var = (ast_expression*)intrinsic_debug_typestring;
2022             }
2023             /* now we try for the real intrinsic hashtable. If the string
2024              * begins with __builtin, we simply skip past it, otherwise we
2025              * use the identifier as is.
2026              */
2027             else if (!strncmp(parser_tokval(parser), "__builtin_", 10)) {
2028                 var = intrin_func(parser, parser_tokval(parser) + 10 /* skip __builtin */);
2029             }
2030
2031             if (!var) {
2032                 char *correct = NULL;
2033                 size_t i;
2034
2035                 /*
2036                  * sometimes people use preprocessing predefs without enabling them
2037                  * i've done this thousands of times already myself.  Lets check for
2038                  * it in the predef table.  And diagnose it better :)
2039                  */
2040                 if (!OPTS_FLAG(FTEPP_PREDEFS) && ftepp_predef_exists(parser_tokval(parser))) {
2041                     parseerror(parser, "unexpected identifier: %s (use -fftepp-predef to enable pre-defined macros)", parser_tokval(parser));
2042                     return false;
2043                 }
2044
2045                 /*
2046                  * TODO: determine the best score for the identifier: be it
2047                  * a variable, a field.
2048                  *
2049                  * We should also consider adding correction tables for
2050                  * other things as well.
2051                  */
2052                 if (OPTS_OPTION_BOOL(OPTION_CORRECTION) && strlen(parser_tokval(parser)) <= 16) {
2053                     correction_t corr;
2054                     correct_init(&corr);
2055
2056                     for (i = 0; i < vec_size(parser->correct_variables); i++) {
2057                         correct = correct_str(&corr, parser->correct_variables[i], parser_tokval(parser));
2058                         if (strcmp(correct, parser_tokval(parser))) {
2059                             break;
2060                         } else  {
2061                             mem_d(correct);
2062                             correct = NULL;
2063                         }
2064                     }
2065                     correct_free(&corr);
2066
2067                     if (correct) {
2068                         parseerror(parser, "unexpected identifier: %s (did you mean %s?)", parser_tokval(parser), correct);
2069                         mem_d(correct);
2070                         return false;
2071                     }
2072                 }
2073                 parseerror(parser, "unexpected identifier: %s", parser_tokval(parser));
2074                 return false;
2075             }
2076         }
2077         else
2078         {
2079             if (ast_istype(var, ast_value)) {
2080                 ((ast_value*)var)->uses++;
2081             }
2082             else if (ast_istype(var, ast_member)) {
2083                 ast_member *mem = (ast_member*)var;
2084                 if (ast_istype(mem->owner, ast_value))
2085                     ((ast_value*)(mem->owner))->uses++;
2086             }
2087         }
2088         vec_push(sy->out, syexp(parser_ctx(parser), var));
2089         return true;
2090     }
2091     parseerror(parser, "unexpected token `%s`", parser_tokval(parser));
2092     return false;
2093 }
2094
2095 static ast_expression* parse_expression_leave(parser_t *parser, bool stopatcomma, bool truthvalue, bool with_labels)
2096 {
2097     ast_expression *expr = NULL;
2098     shunt sy;
2099     size_t i;
2100     bool wantop = false;
2101     /* only warn once about an assignment in a truth value because the current code
2102      * would trigger twice on: if(a = b && ...), once for the if-truth-value, once for the && part
2103      */
2104     bool warn_truthvalue = true;
2105
2106     /* count the parens because an if starts with one, so the
2107      * end of a condition is an unmatched closing paren
2108      */
2109     int ternaries = 0;
2110
2111     memset(&sy, 0, sizeof(sy));
2112
2113     parser->lex->flags.noops = false;
2114
2115     parser_reclassify_token(parser);
2116
2117     while (true)
2118     {
2119         if (parser->tok == TOKEN_TYPENAME) {
2120             parseerror(parser, "unexpected typename `%s`", parser_tokval(parser));
2121             goto onerr;
2122         }
2123
2124         if (parser->tok == TOKEN_OPERATOR)
2125         {
2126             /* classify the operator */
2127             const oper_info *op;
2128             const oper_info *olast = NULL;
2129             size_t o;
2130             for (o = 0; o < operator_count; ++o) {
2131                 if (((!(operators[o].flags & OP_PREFIX) == !!wantop)) &&
2132                     /* !(operators[o].flags & OP_SUFFIX) && / * remove this */
2133                     !strcmp(parser_tokval(parser), operators[o].op))
2134                 {
2135                     break;
2136                 }
2137             }
2138             if (o == operator_count) {
2139                 compile_error(parser_ctx(parser), "unknown operator: %s", parser_tokval(parser));
2140                 goto onerr;
2141             }
2142             /* found an operator */
2143             op = &operators[o];
2144
2145             /* when declaring variables, a comma starts a new variable */
2146             if (op->id == opid1(',') && !vec_size(sy.paren) && stopatcomma) {
2147                 /* fixup the token */
2148                 parser->tok = ',';
2149                 break;
2150             }
2151
2152             /* a colon without a pervious question mark cannot be a ternary */
2153             if (!ternaries && op->id == opid2(':','?')) {
2154                 parser->tok = ':';
2155                 break;
2156             }
2157
2158             if (op->id == opid1(',')) {
2159                 if (vec_size(sy.paren) && vec_last(sy.paren) == PAREN_TERNARY2) {
2160                     (void)!parsewarning(parser, WARN_TERNARY_PRECEDENCE, "suggesting parenthesis around ternary expression");
2161                 }
2162             }
2163
2164             if (vec_size(sy.ops) && !vec_last(sy.ops).isparen)
2165                 olast = &operators[vec_last(sy.ops).etype-1];
2166
2167 #define IsAssignOp(x) (\
2168                 (x) == opid1('=') || \
2169                 (x) == opid2('+','=') || \
2170                 (x) == opid2('-','=') || \
2171                 (x) == opid2('*','=') || \
2172                 (x) == opid2('/','=') || \
2173                 (x) == opid2('%','=') || \
2174                 (x) == opid2('&','=') || \
2175                 (x) == opid2('|','=') || \
2176                 (x) == opid3('&','~','=') \
2177                 )
2178             if (warn_truthvalue) {
2179                 if ( (olast && IsAssignOp(olast->id) && (op->id == opid2('&','&') || op->id == opid2('|','|'))) ||
2180                      (olast && IsAssignOp(op->id) && (olast->id == opid2('&','&') || olast->id == opid2('|','|'))) ||
2181                      (truthvalue && !vec_size(sy.paren) && IsAssignOp(op->id))
2182                    )
2183                 {
2184                     (void)!parsewarning(parser, WARN_PARENTHESIS, "suggesting parenthesis around assignment used as truth value");
2185                     warn_truthvalue = false;
2186                 }
2187             }
2188
2189             while (olast && (
2190                     (op->prec < olast->prec) ||
2191                     (op->assoc == ASSOC_LEFT && op->prec <= olast->prec) ) )
2192             {
2193                 if (!parser_sy_apply_operator(parser, &sy))
2194                     goto onerr;
2195                 if (vec_size(sy.ops) && !vec_last(sy.ops).isparen)
2196                     olast = &operators[vec_last(sy.ops).etype-1];
2197                 else
2198                     olast = NULL;
2199             }
2200
2201             if (op->id == opid1('(')) {
2202                 if (wantop) {
2203                     size_t sycount = vec_size(sy.out);
2204                     /* we expected an operator, this is the function-call operator */
2205                     vec_push(sy.paren, PAREN_FUNC);
2206                     vec_push(sy.ops, syparen(parser_ctx(parser), sycount-1));
2207                     vec_push(sy.argc, 0);
2208                 } else {
2209                     vec_push(sy.paren, PAREN_EXPR);
2210                     vec_push(sy.ops, syparen(parser_ctx(parser), 0));
2211                 }
2212                 wantop = false;
2213             } else if (op->id == opid1('[')) {
2214                 if (!wantop) {
2215                     parseerror(parser, "unexpected array subscript");
2216                     goto onerr;
2217                 }
2218                 vec_push(sy.paren, PAREN_INDEX);
2219                 /* push both the operator and the paren, this makes life easier */
2220                 vec_push(sy.ops, syop(parser_ctx(parser), op));
2221                 vec_push(sy.ops, syparen(parser_ctx(parser), 0));
2222                 wantop = false;
2223             } else if (op->id == opid2('?',':')) {
2224                 vec_push(sy.ops, syop(parser_ctx(parser), op));
2225                 vec_push(sy.ops, syparen(parser_ctx(parser), 0));
2226                 wantop = false;
2227                 ++ternaries;
2228                 vec_push(sy.paren, PAREN_TERNARY1);
2229             } else if (op->id == opid2(':','?')) {
2230                 if (!vec_size(sy.paren)) {
2231                     parseerror(parser, "unexpected colon outside ternary expression (missing parenthesis?)");
2232                     goto onerr;
2233                 }
2234                 if (vec_last(sy.paren) != PAREN_TERNARY1) {
2235                     parseerror(parser, "unexpected colon outside ternary expression (missing parenthesis?)");
2236                     goto onerr;
2237                 }
2238                 if (!parser_close_paren(parser, &sy))
2239                     goto onerr;
2240                 vec_push(sy.ops, syop(parser_ctx(parser), op));
2241                 wantop = false;
2242                 --ternaries;
2243             } else {
2244                 vec_push(sy.ops, syop(parser_ctx(parser), op));
2245                 wantop = !!(op->flags & OP_SUFFIX);
2246             }
2247         }
2248         else if (parser->tok == ')') {
2249             while (vec_size(sy.paren) && vec_last(sy.paren) == PAREN_TERNARY2) {
2250                 if (!parser_sy_apply_operator(parser, &sy))
2251                     goto onerr;
2252             }
2253             if (!vec_size(sy.paren))
2254                 break;
2255             if (wantop) {
2256                 if (vec_last(sy.paren) == PAREN_TERNARY1) {
2257                     parseerror(parser, "mismatched parentheses (closing paren in ternary expression?)");
2258                     goto onerr;
2259                 }
2260                 if (!parser_close_paren(parser, &sy))
2261                     goto onerr;
2262             } else {
2263                 /* must be a function call without parameters */
2264                 if (vec_last(sy.paren) != PAREN_FUNC) {
2265                     parseerror(parser, "closing paren in invalid position");
2266                     goto onerr;
2267                 }
2268                 if (!parser_close_paren(parser, &sy))
2269                     goto onerr;
2270             }
2271             wantop = true;
2272         }
2273         else if (parser->tok == '(') {
2274             parseerror(parser, "internal error: '(' should be classified as operator");
2275             goto onerr;
2276         }
2277         else if (parser->tok == '[') {
2278             parseerror(parser, "internal error: '[' should be classified as operator");
2279             goto onerr;
2280         }
2281         else if (parser->tok == ']') {
2282             while (vec_size(sy.paren) && vec_last(sy.paren) == PAREN_TERNARY2) {
2283                 if (!parser_sy_apply_operator(parser, &sy))
2284                     goto onerr;
2285             }
2286             if (!vec_size(sy.paren))
2287                 break;
2288             if (vec_last(sy.paren) != PAREN_INDEX) {
2289                 parseerror(parser, "mismatched parentheses, unexpected ']'");
2290                 goto onerr;
2291             }
2292             if (!parser_close_paren(parser, &sy))
2293                 goto onerr;
2294             wantop = true;
2295         }
2296         else if (!wantop) {
2297             if (!parse_sya_operand(parser, &sy, with_labels))
2298                 goto onerr;
2299 #if 0
2300             if (vec_size(sy.paren) && vec_last(sy.ops).isparen && vec_last(sy.paren) == PAREN_FUNC)
2301                 vec_last(sy.argc)++;
2302 #endif
2303             wantop = true;
2304         }
2305         else {
2306             /* in this case we might want to allow constant string concatenation */
2307             bool concatenated = false;
2308             if (parser->tok == TOKEN_STRINGCONST && vec_size(sy.out)) {
2309                 ast_expression *lexpr = vec_last(sy.out).out;
2310                 if (ast_istype(lexpr, ast_value)) {
2311                     ast_value *last = (ast_value*)lexpr;
2312                     if (last->isimm == true && last->cvq == CV_CONST &&
2313                         last->hasvalue && last->expression.vtype == TYPE_STRING)
2314                     {
2315                         char *newstr = NULL;
2316                         util_asprintf(&newstr, "%s%s", last->constval.vstring, parser_tokval(parser));
2317                         vec_last(sy.out).out = (ast_expression*)parser_const_string(parser, newstr, false);
2318                         mem_d(newstr);
2319                         concatenated = true;
2320                     }
2321                 }
2322             }
2323             if (!concatenated) {
2324                 parseerror(parser, "expected operator or end of statement");
2325                 goto onerr;
2326             }
2327         }
2328
2329         if (!parser_next(parser)) {
2330             goto onerr;
2331         }
2332         if (parser->tok == ';' ||
2333             ((!vec_size(sy.paren) || (vec_size(sy.paren) == 1 && vec_last(sy.paren) == PAREN_TERNARY2)) &&
2334             (parser->tok == ']' || parser->tok == ')' || parser->tok == '}')))
2335         {
2336             break;
2337         }
2338     }
2339
2340     while (vec_size(sy.ops)) {
2341         if (!parser_sy_apply_operator(parser, &sy))
2342             goto onerr;
2343     }
2344
2345     parser->lex->flags.noops = true;
2346     if (vec_size(sy.out) != 1) {
2347         parseerror(parser, "expression with not 1 but %lu output values...", (unsigned long) vec_size(sy.out));
2348         expr = NULL;
2349     } else
2350         expr = sy.out[0].out;
2351     vec_free(sy.out);
2352     vec_free(sy.ops);
2353     if (vec_size(sy.paren)) {
2354         parseerror(parser, "internal error: vec_size(sy.paren) = %lu", (unsigned long)vec_size(sy.paren));
2355         return NULL;
2356     }
2357     vec_free(sy.paren);
2358     vec_free(sy.argc);
2359     return expr;
2360
2361 onerr:
2362     parser->lex->flags.noops = true;
2363     for (i = 0; i < vec_size(sy.out); ++i) {
2364         if (sy.out[i].out)
2365             ast_unref(sy.out[i].out);
2366     }
2367     vec_free(sy.out);
2368     vec_free(sy.ops);
2369     vec_free(sy.paren);
2370     vec_free(sy.argc);
2371     return NULL;
2372 }
2373
2374 static ast_expression* parse_expression(parser_t *parser, bool stopatcomma, bool with_labels)
2375 {
2376     ast_expression *e = parse_expression_leave(parser, stopatcomma, false, with_labels);
2377     if (!e)
2378         return NULL;
2379     if (parser->tok != ';') {
2380         parseerror(parser, "semicolon expected after expression");
2381         ast_unref(e);
2382         return NULL;
2383     }
2384     if (!parser_next(parser)) {
2385         ast_unref(e);
2386         return NULL;
2387     }
2388     return e;
2389 }
2390
2391 static void parser_enterblock(parser_t *parser)
2392 {
2393     vec_push(parser->variables, util_htnew(PARSER_HT_SIZE));
2394     vec_push(parser->_blocklocals, vec_size(parser->_locals));
2395     vec_push(parser->typedefs, util_htnew(TYPEDEF_HT_SIZE));
2396     vec_push(parser->_blocktypedefs, vec_size(parser->_typedefs));
2397     vec_push(parser->_block_ctx, parser_ctx(parser));
2398
2399     /* corrector */
2400     vec_push(parser->correct_variables, correct_trie_new());
2401     vec_push(parser->correct_variables_score, NULL);
2402 }
2403
2404 static bool parser_leaveblock(parser_t *parser)
2405 {
2406     bool   rv = true;
2407     size_t locals, typedefs;
2408
2409     if (vec_size(parser->variables) <= PARSER_HT_LOCALS) {
2410         parseerror(parser, "internal error: parser_leaveblock with no block");
2411         return false;
2412     }
2413
2414     util_htdel(vec_last(parser->variables));
2415     correct_del(vec_last(parser->correct_variables), vec_last(parser->correct_variables_score));
2416
2417     vec_pop(parser->variables);
2418     vec_pop(parser->correct_variables);
2419     vec_pop(parser->correct_variables_score);
2420     if (!vec_size(parser->_blocklocals)) {
2421         parseerror(parser, "internal error: parser_leaveblock with no block (2)");
2422         return false;
2423     }
2424
2425     locals = vec_last(parser->_blocklocals);
2426     vec_pop(parser->_blocklocals);
2427     while (vec_size(parser->_locals) != locals) {
2428         ast_expression *e = vec_last(parser->_locals);
2429         ast_value      *v = (ast_value*)e;
2430         vec_pop(parser->_locals);
2431         if (ast_istype(e, ast_value) && !v->uses) {
2432             if (compile_warning(ast_ctx(v), WARN_UNUSED_VARIABLE, "unused variable: `%s`", v->name))
2433                 rv = false;
2434         }
2435     }
2436
2437     typedefs = vec_last(parser->_blocktypedefs);
2438     while (vec_size(parser->_typedefs) != typedefs) {
2439         ast_delete(vec_last(parser->_typedefs));
2440         vec_pop(parser->_typedefs);
2441     }
2442     util_htdel(vec_last(parser->typedefs));
2443     vec_pop(parser->typedefs);
2444
2445     vec_pop(parser->_block_ctx);
2446
2447     return rv;
2448 }
2449
2450 static void parser_addlocal(parser_t *parser, const char *name, ast_expression *e)
2451 {
2452     vec_push(parser->_locals, e);
2453     util_htset(vec_last(parser->variables), name, (void*)e);
2454
2455     /* corrector */
2456     correct_add (
2457          vec_last(parser->correct_variables),
2458         &vec_last(parser->correct_variables_score),
2459         name
2460     );
2461 }
2462
2463 static void parser_addglobal(parser_t *parser, const char *name, ast_expression *e)
2464 {
2465     vec_push(parser->globals, e);
2466     util_htset(parser->htglobals, name, e);
2467
2468     /* corrector */
2469     correct_add (
2470          parser->correct_variables[0],
2471         &parser->correct_variables_score[0],
2472         name
2473     );
2474 }
2475
2476 static ast_expression* process_condition(parser_t *parser, ast_expression *cond, bool *_ifnot)
2477 {
2478     bool       ifnot = false;
2479     ast_unary *unary;
2480     ast_expression *prev;
2481
2482     if (cond->vtype == TYPE_VOID || cond->vtype >= TYPE_VARIANT) {
2483         char ty[1024];
2484         ast_type_to_string(cond, ty, sizeof(ty));
2485         compile_error(ast_ctx(cond), "invalid type for if() condition: %s", ty);
2486     }
2487
2488     if (OPTS_FLAG(FALSE_EMPTY_STRINGS) && cond->vtype == TYPE_STRING)
2489     {
2490         prev = cond;
2491         cond = (ast_expression*)ast_unary_new(ast_ctx(cond), INSTR_NOT_S, cond);
2492         if (!cond) {
2493             ast_unref(prev);
2494             parseerror(parser, "internal error: failed to process condition");
2495             return NULL;
2496         }
2497         ifnot = !ifnot;
2498     }
2499     else if (OPTS_FLAG(CORRECT_LOGIC) && cond->vtype == TYPE_VECTOR)
2500     {
2501         /* vector types need to be cast to true booleans */
2502         ast_binary *bin = (ast_binary*)cond;
2503         if (!OPTS_FLAG(PERL_LOGIC) || !ast_istype(cond, ast_binary) || !(bin->op == INSTR_AND || bin->op == INSTR_OR))
2504         {
2505             /* in perl-logic, AND and OR take care of the -fcorrect-logic */
2506             prev = cond;
2507             cond = (ast_expression*)ast_unary_new(ast_ctx(cond), INSTR_NOT_V, cond);
2508             if (!cond) {
2509                 ast_unref(prev);
2510                 parseerror(parser, "internal error: failed to process condition");
2511                 return NULL;
2512             }
2513             ifnot = !ifnot;
2514         }
2515     }
2516
2517     unary = (ast_unary*)cond;
2518     /* ast_istype dereferences cond, should test here for safety */
2519     while (cond && ast_istype(cond, ast_unary) && unary->op == INSTR_NOT_F)
2520     {
2521         cond = unary->operand;
2522         unary->operand = NULL;
2523         ast_delete(unary);
2524         ifnot = !ifnot;
2525         unary = (ast_unary*)cond;
2526     }
2527
2528     if (!cond)
2529         parseerror(parser, "internal error: failed to process condition");
2530
2531     if (ifnot) *_ifnot = !*_ifnot;
2532     return cond;
2533 }
2534
2535 static bool parse_if(parser_t *parser, ast_block *block, ast_expression **out)
2536 {
2537     ast_ifthen *ifthen;
2538     ast_expression *cond, *ontrue = NULL, *onfalse = NULL;
2539     bool ifnot = false;
2540
2541     lex_ctx_t ctx = parser_ctx(parser);
2542
2543     (void)block; /* not touching */
2544
2545     /* skip the 'if', parse an optional 'not' and check for an opening paren */
2546     if (!parser_next(parser)) {
2547         parseerror(parser, "expected condition or 'not'");
2548         return false;
2549     }
2550     if (parser->tok == TOKEN_IDENT && !strcmp(parser_tokval(parser), "not")) {
2551         ifnot = true;
2552         if (!parser_next(parser)) {
2553             parseerror(parser, "expected condition in parenthesis");
2554             return false;
2555         }
2556     }
2557     if (parser->tok != '(') {
2558         parseerror(parser, "expected 'if' condition in parenthesis");
2559         return false;
2560     }
2561     /* parse into the expression */
2562     if (!parser_next(parser)) {
2563         parseerror(parser, "expected 'if' condition after opening paren");
2564         return false;
2565     }
2566     /* parse the condition */
2567     cond = parse_expression_leave(parser, false, true, false);
2568     if (!cond)
2569         return false;
2570     /* closing paren */
2571     if (parser->tok != ')') {
2572         parseerror(parser, "expected closing paren after 'if' condition");
2573         ast_unref(cond);
2574         return false;
2575     }
2576     /* parse into the 'then' branch */
2577     if (!parser_next(parser)) {
2578         parseerror(parser, "expected statement for on-true branch of 'if'");
2579         ast_unref(cond);
2580         return false;
2581     }
2582     if (!parse_statement_or_block(parser, &ontrue)) {
2583         ast_unref(cond);
2584         return false;
2585     }
2586     if (!ontrue)
2587         ontrue = (ast_expression*)ast_block_new(parser_ctx(parser));
2588     /* check for an else */
2589     if (!strcmp(parser_tokval(parser), "else")) {
2590         /* parse into the 'else' branch */
2591         if (!parser_next(parser)) {
2592             parseerror(parser, "expected on-false branch after 'else'");
2593             ast_delete(ontrue);
2594             ast_unref(cond);
2595             return false;
2596         }
2597         if (!parse_statement_or_block(parser, &onfalse)) {
2598             ast_delete(ontrue);
2599             ast_unref(cond);
2600             return false;
2601         }
2602     }
2603
2604     cond = process_condition(parser, cond, &ifnot);
2605     if (!cond) {
2606         if (ontrue)  ast_delete(ontrue);
2607         if (onfalse) ast_delete(onfalse);
2608         return false;
2609     }
2610
2611     if (ifnot)
2612         ifthen = ast_ifthen_new(ctx, cond, onfalse, ontrue);
2613     else
2614         ifthen = ast_ifthen_new(ctx, cond, ontrue, onfalse);
2615     *out = (ast_expression*)ifthen;
2616     return true;
2617 }
2618
2619 static bool parse_while_go(parser_t *parser, ast_block *block, ast_expression **out);
2620 static bool parse_while(parser_t *parser, ast_block *block, ast_expression **out)
2621 {
2622     bool rv;
2623     char *label = NULL;
2624
2625     /* skip the 'while' and get the body */
2626     if (!parser_next(parser)) {
2627         if (OPTS_FLAG(LOOP_LABELS))
2628             parseerror(parser, "expected loop label or 'while' condition in parenthesis");
2629         else
2630             parseerror(parser, "expected 'while' condition in parenthesis");
2631         return false;
2632     }
2633
2634     if (parser->tok == ':') {
2635         if (!OPTS_FLAG(LOOP_LABELS))
2636             parseerror(parser, "labeled loops not activated, try using -floop-labels");
2637         if (!parser_next(parser) || parser->tok != TOKEN_IDENT) {
2638             parseerror(parser, "expected loop label");
2639             return false;
2640         }
2641         label = util_strdup(parser_tokval(parser));
2642         if (!parser_next(parser)) {
2643             mem_d(label);
2644             parseerror(parser, "expected 'while' condition in parenthesis");
2645             return false;
2646         }
2647     }
2648
2649     if (parser->tok != '(') {
2650         parseerror(parser, "expected 'while' condition in parenthesis");
2651         return false;
2652     }
2653
2654     vec_push(parser->breaks, label);
2655     vec_push(parser->continues, label);
2656
2657     rv = parse_while_go(parser, block, out);
2658     if (label)
2659         mem_d(label);
2660     if (vec_last(parser->breaks) != label || vec_last(parser->continues) != label) {
2661         parseerror(parser, "internal error: label stack corrupted");
2662         rv = false;
2663         ast_delete(*out);
2664         *out = NULL;
2665     }
2666     else {
2667         vec_pop(parser->breaks);
2668         vec_pop(parser->continues);
2669     }
2670     return rv;
2671 }
2672
2673 static bool parse_while_go(parser_t *parser, ast_block *block, ast_expression **out)
2674 {
2675     ast_loop *aloop;
2676     ast_expression *cond, *ontrue;
2677
2678     bool ifnot = false;
2679
2680     lex_ctx_t ctx = parser_ctx(parser);
2681
2682     (void)block; /* not touching */
2683
2684     /* parse into the expression */
2685     if (!parser_next(parser)) {
2686         parseerror(parser, "expected 'while' condition after opening paren");
2687         return false;
2688     }
2689     /* parse the condition */
2690     cond = parse_expression_leave(parser, false, true, false);
2691     if (!cond)
2692         return false;
2693     /* closing paren */
2694     if (parser->tok != ')') {
2695         parseerror(parser, "expected closing paren after 'while' condition");
2696         ast_unref(cond);
2697         return false;
2698     }
2699     /* parse into the 'then' branch */
2700     if (!parser_next(parser)) {
2701         parseerror(parser, "expected while-loop body");
2702         ast_unref(cond);
2703         return false;
2704     }
2705     if (!parse_statement_or_block(parser, &ontrue)) {
2706         ast_unref(cond);
2707         return false;
2708     }
2709
2710     cond = process_condition(parser, cond, &ifnot);
2711     if (!cond) {
2712         ast_unref(ontrue);
2713         return false;
2714     }
2715     aloop = ast_loop_new(ctx, NULL, cond, ifnot, NULL, false, NULL, ontrue);
2716     *out = (ast_expression*)aloop;
2717     return true;
2718 }
2719
2720 static bool parse_dowhile_go(parser_t *parser, ast_block *block, ast_expression **out);
2721 static bool parse_dowhile(parser_t *parser, ast_block *block, ast_expression **out)
2722 {
2723     bool rv;
2724     char *label = NULL;
2725
2726     /* skip the 'do' and get the body */
2727     if (!parser_next(parser)) {
2728         if (OPTS_FLAG(LOOP_LABELS))
2729             parseerror(parser, "expected loop label or body");
2730         else
2731             parseerror(parser, "expected loop body");
2732         return false;
2733     }
2734
2735     if (parser->tok == ':') {
2736         if (!OPTS_FLAG(LOOP_LABELS))
2737             parseerror(parser, "labeled loops not activated, try using -floop-labels");
2738         if (!parser_next(parser) || parser->tok != TOKEN_IDENT) {
2739             parseerror(parser, "expected loop label");
2740             return false;
2741         }
2742         label = util_strdup(parser_tokval(parser));
2743         if (!parser_next(parser)) {
2744             mem_d(label);
2745             parseerror(parser, "expected loop body");
2746             return false;
2747         }
2748     }
2749
2750     vec_push(parser->breaks, label);
2751     vec_push(parser->continues, label);
2752
2753     rv = parse_dowhile_go(parser, block, out);
2754     if (label)
2755         mem_d(label);
2756     if (vec_last(parser->breaks) != label || vec_last(parser->continues) != label) {
2757         parseerror(parser, "internal error: label stack corrupted");
2758         rv = false;
2759         /*
2760          * Test for NULL otherwise ast_delete dereferences null pointer
2761          * and boom.
2762          */
2763         if (*out)
2764             ast_delete(*out);
2765         *out = NULL;
2766     }
2767     else {
2768         vec_pop(parser->breaks);
2769         vec_pop(parser->continues);
2770     }
2771     return rv;
2772 }
2773
2774 static bool parse_dowhile_go(parser_t *parser, ast_block *block, ast_expression **out)
2775 {
2776     ast_loop *aloop;
2777     ast_expression *cond, *ontrue;
2778
2779     bool ifnot = false;
2780
2781     lex_ctx_t ctx = parser_ctx(parser);
2782
2783     (void)block; /* not touching */
2784
2785     if (!parse_statement_or_block(parser, &ontrue))
2786         return false;
2787
2788     /* expect the "while" */
2789     if (parser->tok != TOKEN_KEYWORD ||
2790         strcmp(parser_tokval(parser), "while"))
2791     {
2792         parseerror(parser, "expected 'while' and condition");
2793         ast_delete(ontrue);
2794         return false;
2795     }
2796
2797     /* skip the 'while' and check for opening paren */
2798     if (!parser_next(parser) || parser->tok != '(') {
2799         parseerror(parser, "expected 'while' condition in parenthesis");
2800         ast_delete(ontrue);
2801         return false;
2802     }
2803     /* parse into the expression */
2804     if (!parser_next(parser)) {
2805         parseerror(parser, "expected 'while' condition after opening paren");
2806         ast_delete(ontrue);
2807         return false;
2808     }
2809     /* parse the condition */
2810     cond = parse_expression_leave(parser, false, true, false);
2811     if (!cond)
2812         return false;
2813     /* closing paren */
2814     if (parser->tok != ')') {
2815         parseerror(parser, "expected closing paren after 'while' condition");
2816         ast_delete(ontrue);
2817         ast_unref(cond);
2818         return false;
2819     }
2820     /* parse on */
2821     if (!parser_next(parser) || parser->tok != ';') {
2822         parseerror(parser, "expected semicolon after condition");
2823         ast_delete(ontrue);
2824         ast_unref(cond);
2825         return false;
2826     }
2827
2828     if (!parser_next(parser)) {
2829         parseerror(parser, "parse error");
2830         ast_delete(ontrue);
2831         ast_unref(cond);
2832         return false;
2833     }
2834
2835     cond = process_condition(parser, cond, &ifnot);
2836     if (!cond) {
2837         ast_delete(ontrue);
2838         return false;
2839     }
2840     aloop = ast_loop_new(ctx, NULL, NULL, false, cond, ifnot, NULL, ontrue);
2841     *out = (ast_expression*)aloop;
2842     return true;
2843 }
2844
2845 static bool parse_for_go(parser_t *parser, ast_block *block, ast_expression **out);
2846 static bool parse_for(parser_t *parser, ast_block *block, ast_expression **out)
2847 {
2848     bool rv;
2849     char *label = NULL;
2850
2851     /* skip the 'for' and check for opening paren */
2852     if (!parser_next(parser)) {
2853         if (OPTS_FLAG(LOOP_LABELS))
2854             parseerror(parser, "expected loop label or 'for' expressions in parenthesis");
2855         else
2856             parseerror(parser, "expected 'for' expressions in parenthesis");
2857         return false;
2858     }
2859
2860     if (parser->tok == ':') {
2861         if (!OPTS_FLAG(LOOP_LABELS))
2862             parseerror(parser, "labeled loops not activated, try using -floop-labels");
2863         if (!parser_next(parser) || parser->tok != TOKEN_IDENT) {
2864             parseerror(parser, "expected loop label");
2865             return false;
2866         }
2867         label = util_strdup(parser_tokval(parser));
2868         if (!parser_next(parser)) {
2869             mem_d(label);
2870             parseerror(parser, "expected 'for' expressions in parenthesis");
2871             return false;
2872         }
2873     }
2874
2875     if (parser->tok != '(') {
2876         parseerror(parser, "expected 'for' expressions in parenthesis");
2877         return false;
2878     }
2879
2880     vec_push(parser->breaks, label);
2881     vec_push(parser->continues, label);
2882
2883     rv = parse_for_go(parser, block, out);
2884     if (label)
2885         mem_d(label);
2886     if (vec_last(parser->breaks) != label || vec_last(parser->continues) != label) {
2887         parseerror(parser, "internal error: label stack corrupted");
2888         rv = false;
2889         ast_delete(*out);
2890         *out = NULL;
2891     }
2892     else {
2893         vec_pop(parser->breaks);
2894         vec_pop(parser->continues);
2895     }
2896     return rv;
2897 }
2898 static bool parse_for_go(parser_t *parser, ast_block *block, ast_expression **out)
2899 {
2900     ast_loop       *aloop;
2901     ast_expression *initexpr, *cond, *increment, *ontrue;
2902     ast_value      *typevar;
2903
2904     bool ifnot  = false;
2905
2906     lex_ctx_t ctx = parser_ctx(parser);
2907
2908     parser_enterblock(parser);
2909
2910     initexpr  = NULL;
2911     cond      = NULL;
2912     increment = NULL;
2913     ontrue    = NULL;
2914
2915     /* parse into the expression */
2916     if (!parser_next(parser)) {
2917         parseerror(parser, "expected 'for' initializer after opening paren");
2918         goto onerr;
2919     }
2920
2921     typevar = NULL;
2922     if (parser->tok == TOKEN_IDENT)
2923         typevar = parser_find_typedef(parser, parser_tokval(parser), 0);
2924
2925     if (typevar || parser->tok == TOKEN_TYPENAME) {
2926 #if 0
2927         if (OPTS_OPTION_U32(OPTION_STANDARD) != COMPILER_GMQCC) {
2928             if (parsewarning(parser, WARN_EXTENSIONS,
2929                              "current standard does not allow variable declarations in for-loop initializers"))
2930                 goto onerr;
2931         }
2932 #endif
2933         if (!parse_variable(parser, block, true, CV_VAR, typevar, false, false, 0, NULL))
2934             goto onerr;
2935     }
2936     else if (parser->tok != ';')
2937     {
2938         initexpr = parse_expression_leave(parser, false, false, false);
2939         if (!initexpr)
2940             goto onerr;
2941     }
2942
2943     /* move on to condition */
2944     if (parser->tok != ';') {
2945         parseerror(parser, "expected semicolon after for-loop initializer");
2946         goto onerr;
2947     }
2948     if (!parser_next(parser)) {
2949         parseerror(parser, "expected for-loop condition");
2950         goto onerr;
2951     }
2952
2953     /* parse the condition */
2954     if (parser->tok != ';') {
2955         cond = parse_expression_leave(parser, false, true, false);
2956         if (!cond)
2957             goto onerr;
2958     }
2959
2960     /* move on to incrementor */
2961     if (parser->tok != ';') {
2962         parseerror(parser, "expected semicolon after for-loop initializer");
2963         goto onerr;
2964     }
2965     if (!parser_next(parser)) {
2966         parseerror(parser, "expected for-loop condition");
2967         goto onerr;
2968     }
2969
2970     /* parse the incrementor */
2971     if (parser->tok != ')') {
2972         lex_ctx_t condctx = parser_ctx(parser);
2973         increment = parse_expression_leave(parser, false, false, false);
2974         if (!increment)
2975             goto onerr;
2976         if (!ast_side_effects(increment)) {
2977             if (compile_warning(condctx, WARN_EFFECTLESS_STATEMENT, "statement has no effect"))
2978                 goto onerr;
2979         }
2980     }
2981
2982     /* closing paren */
2983     if (parser->tok != ')') {
2984         parseerror(parser, "expected closing paren after 'for-loop' incrementor");
2985         goto onerr;
2986     }
2987     /* parse into the 'then' branch */
2988     if (!parser_next(parser)) {
2989         parseerror(parser, "expected for-loop body");
2990         goto onerr;
2991     }
2992     if (!parse_statement_or_block(parser, &ontrue))
2993         goto onerr;
2994
2995     if (cond) {
2996         cond = process_condition(parser, cond, &ifnot);
2997         if (!cond)
2998             goto onerr;
2999     }
3000     aloop = ast_loop_new(ctx, initexpr, cond, ifnot, NULL, false, increment, ontrue);
3001     *out = (ast_expression*)aloop;
3002
3003     if (!parser_leaveblock(parser)) {
3004         ast_delete(aloop);
3005         return false;
3006     }
3007     return true;
3008 onerr:
3009     if (initexpr)  ast_unref(initexpr);
3010     if (cond)      ast_unref(cond);
3011     if (increment) ast_unref(increment);
3012     (void)!parser_leaveblock(parser);
3013     return false;
3014 }
3015
3016 static bool parse_return(parser_t *parser, ast_block *block, ast_expression **out)
3017 {
3018     ast_expression *exp      = NULL;
3019     ast_expression *var      = NULL;
3020     ast_return     *ret      = NULL;
3021     ast_value      *retval   = parser->function->return_value;
3022     ast_value      *expected = parser->function->vtype;
3023
3024     lex_ctx_t ctx = parser_ctx(parser);
3025
3026     (void)block; /* not touching */
3027
3028     if (!parser_next(parser)) {
3029         parseerror(parser, "expected return expression");
3030         return false;
3031     }
3032
3033     /* return assignments */
3034     if (parser->tok == '=') {
3035         if (!OPTS_FLAG(RETURN_ASSIGNMENTS)) {
3036             parseerror(parser, "return assignments not activated, try using -freturn-assigments");
3037             return false;
3038         }
3039
3040         if (type_store_instr[expected->expression.next->vtype] == VINSTR_END) {
3041             char ty1[1024];
3042             ast_type_to_string(expected->expression.next, ty1, sizeof(ty1));
3043             parseerror(parser, "invalid return type: `%s'", ty1);
3044             return false;
3045         }
3046
3047         if (!parser_next(parser)) {
3048             parseerror(parser, "expected return assignment expression");
3049             return false;
3050         }
3051
3052         if (!(exp = parse_expression_leave(parser, false, false, false)))
3053             return false;
3054
3055         /* prepare the return value */
3056         if (!retval) {
3057             retval = ast_value_new(ctx, "#LOCAL_RETURN", TYPE_VOID);
3058             ast_type_adopt(retval, expected->expression.next);
3059             parser->function->return_value = retval;
3060         }
3061
3062         if (!ast_compare_type(exp, (ast_expression*)retval)) {
3063             char ty1[1024], ty2[1024];
3064             ast_type_to_string(exp, ty1, sizeof(ty1));
3065             ast_type_to_string(&retval->expression, ty2, sizeof(ty2));
3066             parseerror(parser, "invalid type for return value: `%s', expected `%s'", ty1, ty2);
3067         }
3068
3069         /* store to 'return' local variable */
3070         var = (ast_expression*)ast_store_new(
3071             ctx,
3072             type_store_instr[expected->expression.next->vtype],
3073             (ast_expression*)retval, exp);
3074
3075         if (!var) {
3076             ast_unref(exp);
3077             return false;
3078         }
3079
3080         if (parser->tok != ';')
3081             parseerror(parser, "missing semicolon after return assignment");
3082         else if (!parser_next(parser))
3083             parseerror(parser, "parse error after return assignment");
3084
3085         *out = var;
3086         return true;
3087     }
3088
3089     if (parser->tok != ';') {
3090         exp = parse_expression(parser, false, false);
3091         if (!exp)
3092             return false;
3093
3094         if (exp->vtype != TYPE_NIL &&
3095             exp->vtype != ((ast_expression*)expected)->next->vtype)
3096         {
3097             parseerror(parser, "return with invalid expression");
3098         }
3099
3100         ret = ast_return_new(ctx, exp);
3101         if (!ret) {
3102             ast_unref(exp);
3103             return false;
3104         }
3105     } else {
3106         if (!parser_next(parser))
3107             parseerror(parser, "parse error");
3108
3109         if (!retval && expected->expression.next->vtype != TYPE_VOID)
3110         {
3111             (void)!parsewarning(parser, WARN_MISSING_RETURN_VALUES, "return without value");
3112         }
3113         ret = ast_return_new(ctx, (ast_expression*)retval);
3114     }
3115     *out = (ast_expression*)ret;
3116     return true;
3117 }
3118
3119 static bool parse_break_continue(parser_t *parser, ast_block *block, ast_expression **out, bool is_continue)
3120 {
3121     size_t       i;
3122     unsigned int levels = 0;
3123     lex_ctx_t      ctx = parser_ctx(parser);
3124     const char **loops = (is_continue ? parser->continues : parser->breaks);
3125
3126     (void)block; /* not touching */
3127     if (!parser_next(parser)) {
3128         parseerror(parser, "expected semicolon or loop label");
3129         return false;
3130     }
3131
3132     if (!vec_size(loops)) {
3133         if (is_continue)
3134             parseerror(parser, "`continue` can only be used inside loops");
3135         else
3136             parseerror(parser, "`break` can only be used inside loops or switches");
3137     }
3138
3139     if (parser->tok == TOKEN_IDENT) {
3140         if (!OPTS_FLAG(LOOP_LABELS))
3141             parseerror(parser, "labeled loops not activated, try using -floop-labels");
3142         i = vec_size(loops);
3143         while (i--) {
3144             if (loops[i] && !strcmp(loops[i], parser_tokval(parser)))
3145                 break;
3146             if (!i) {
3147                 parseerror(parser, "no such loop to %s: `%s`",
3148                            (is_continue ? "continue" : "break out of"),
3149                            parser_tokval(parser));
3150                 return false;
3151             }
3152             ++levels;
3153         }
3154         if (!parser_next(parser)) {
3155             parseerror(parser, "expected semicolon");
3156             return false;
3157         }
3158     }
3159
3160     if (parser->tok != ';') {
3161         parseerror(parser, "expected semicolon");
3162         return false;
3163     }
3164
3165     if (!parser_next(parser))
3166         parseerror(parser, "parse error");
3167
3168     *out = (ast_expression*)ast_breakcont_new(ctx, is_continue, levels);
3169     return true;
3170 }
3171
3172 /* returns true when it was a variable qualifier, false otherwise!
3173  * on error, cvq is set to CV_WRONG
3174  */
3175 static bool parse_qualifiers(parser_t *parser, bool with_local, int *cvq, bool *noref, bool *is_static, uint32_t *_flags, char **message)
3176 {
3177     bool had_const    = false;
3178     bool had_var      = false;
3179     bool had_noref    = false;
3180     bool had_attrib   = false;
3181     bool had_static   = false;
3182     uint32_t flags    = 0;
3183
3184     *cvq = CV_NONE;
3185     for (;;) {
3186         if (parser->tok == TOKEN_ATTRIBUTE_OPEN) {
3187             had_attrib = true;
3188             /* parse an attribute */
3189             if (!parser_next(parser)) {
3190                 parseerror(parser, "expected attribute after `[[`");
3191                 *cvq = CV_WRONG;
3192                 return false;
3193             }
3194             if (!strcmp(parser_tokval(parser), "noreturn")) {
3195                 flags |= AST_FLAG_NORETURN;
3196                 if (!parser_next(parser) || parser->tok != TOKEN_ATTRIBUTE_CLOSE) {
3197                     parseerror(parser, "`noreturn` attribute has no parameters, expected `]]`");
3198                     *cvq = CV_WRONG;
3199                     return false;
3200                 }
3201             }
3202             else if (!strcmp(parser_tokval(parser), "noref")) {
3203                 had_noref = true;
3204                 if (!parser_next(parser) || parser->tok != TOKEN_ATTRIBUTE_CLOSE) {
3205                     parseerror(parser, "`noref` attribute has no parameters, expected `]]`");
3206                     *cvq = CV_WRONG;
3207                     return false;
3208                 }
3209             }
3210             else if (!strcmp(parser_tokval(parser), "inline")) {
3211                 flags |= AST_FLAG_INLINE;
3212                 if (!parser_next(parser) || parser->tok != TOKEN_ATTRIBUTE_CLOSE) {
3213                     parseerror(parser, "`noref` attribute has no parameters, expected `]]`");
3214                     *cvq = CV_WRONG;
3215                     return false;
3216                 }
3217             }
3218             else if (!strcmp(parser_tokval(parser), "alias") && !(flags & AST_FLAG_ALIAS)) {
3219                 flags   |= AST_FLAG_ALIAS;
3220                 *message = NULL;
3221
3222                 if (!parser_next(parser)) {
3223                     parseerror(parser, "parse error in attribute");
3224                     goto argerr;
3225                 }
3226
3227                 if (parser->tok == '(') {
3228                     if (!parser_next(parser) || parser->tok != TOKEN_STRINGCONST) {
3229                         parseerror(parser, "`alias` attribute missing parameter");
3230                         goto argerr;
3231                     }
3232
3233                     *message = util_strdup(parser_tokval(parser));
3234
3235                     if (!parser_next(parser)) {
3236                         parseerror(parser, "parse error in attribute");
3237                         goto argerr;
3238                     }
3239
3240                     if (parser->tok != ')') {
3241                         parseerror(parser, "`alias` attribute expected `)` after parameter");
3242                         goto argerr;
3243                     }
3244
3245                     if (!parser_next(parser)) {
3246                         parseerror(parser, "parse error in attribute");
3247                         goto argerr;
3248                     }
3249                 }
3250
3251                 if (parser->tok != TOKEN_ATTRIBUTE_CLOSE) {
3252                     parseerror(parser, "`alias` attribute expected `]]`");
3253                     goto argerr;
3254                 }
3255             }
3256             else if (!strcmp(parser_tokval(parser), "deprecated") && !(flags & AST_FLAG_DEPRECATED)) {
3257                 flags   |= AST_FLAG_DEPRECATED;
3258                 *message = NULL;
3259
3260                 if (!parser_next(parser)) {
3261                     parseerror(parser, "parse error in attribute");
3262                     goto argerr;
3263                 }
3264
3265                 if (parser->tok == '(') {
3266                     if (!parser_next(parser) || parser->tok != TOKEN_STRINGCONST) {
3267                         parseerror(parser, "`deprecated` attribute missing parameter");
3268                         goto argerr;
3269                     }
3270
3271                     *message = util_strdup(parser_tokval(parser));
3272
3273                     if (!parser_next(parser)) {
3274                         parseerror(parser, "parse error in attribute");
3275                         goto argerr;
3276                     }
3277
3278                     if(parser->tok != ')') {
3279                         parseerror(parser, "`deprecated` attribute expected `)` after parameter");
3280                         goto argerr;
3281                     }
3282
3283                     if (!parser_next(parser)) {
3284                         parseerror(parser, "parse error in attribute");
3285                         goto argerr;
3286                     }
3287                 }
3288                 /* no message */
3289                 if (parser->tok != TOKEN_ATTRIBUTE_CLOSE) {
3290                     parseerror(parser, "`deprecated` attribute expected `]]`");
3291
3292                     argerr: /* ugly */
3293                     if (*message) mem_d(*message);
3294                     *message = NULL;
3295                     *cvq     = CV_WRONG;
3296                     return false;
3297                 }
3298             }
3299             else
3300             {
3301                 /* Skip tokens until we hit a ]] */
3302                 (void)!parsewarning(parser, WARN_UNKNOWN_ATTRIBUTE, "unknown attribute starting with `%s`", parser_tokval(parser));
3303                 while (parser->tok != TOKEN_ATTRIBUTE_CLOSE) {
3304                     if (!parser_next(parser)) {
3305                         parseerror(parser, "error inside attribute");
3306                         *cvq = CV_WRONG;
3307                         return false;
3308                     }
3309                 }
3310             }
3311         }
3312         else if (with_local && !strcmp(parser_tokval(parser), "static"))
3313             had_static = true;
3314         else if (!strcmp(parser_tokval(parser), "const"))
3315             had_const = true;
3316         else if (!strcmp(parser_tokval(parser), "var"))
3317             had_var = true;
3318         else if (with_local && !strcmp(parser_tokval(parser), "local"))
3319             had_var = true;
3320         else if (!strcmp(parser_tokval(parser), "noref"))
3321             had_noref = true;
3322         else if (!had_const && !had_var && !had_noref && !had_attrib && !had_static && !flags) {
3323             return false;
3324         }
3325         else
3326             break;
3327         if (!parser_next(parser))
3328             goto onerr;
3329     }
3330     if (had_const)
3331         *cvq = CV_CONST;
3332     else if (had_var)
3333         *cvq = CV_VAR;
3334     else
3335         *cvq = CV_NONE;
3336     *noref     = had_noref;
3337     *is_static = had_static;
3338     *_flags    = flags;
3339     return true;
3340 onerr:
3341     parseerror(parser, "parse error after variable qualifier");
3342     *cvq = CV_WRONG;
3343     return true;
3344 }
3345
3346 static bool parse_switch_go(parser_t *parser, ast_block *block, ast_expression **out);
3347 static bool parse_switch(parser_t *parser, ast_block *block, ast_expression **out)
3348 {
3349     bool rv;
3350     char *label = NULL;
3351
3352     /* skip the 'while' and get the body */
3353     if (!parser_next(parser)) {
3354         if (OPTS_FLAG(LOOP_LABELS))
3355             parseerror(parser, "expected loop label or 'switch' operand in parenthesis");
3356         else
3357             parseerror(parser, "expected 'switch' operand in parenthesis");
3358         return false;
3359     }
3360
3361     if (parser->tok == ':') {
3362         if (!OPTS_FLAG(LOOP_LABELS))
3363             parseerror(parser, "labeled loops not activated, try using -floop-labels");
3364         if (!parser_next(parser) || parser->tok != TOKEN_IDENT) {
3365             parseerror(parser, "expected loop label");
3366             return false;
3367         }
3368         label = util_strdup(parser_tokval(parser));
3369         if (!parser_next(parser)) {
3370             mem_d(label);
3371             parseerror(parser, "expected 'switch' operand in parenthesis");
3372             return false;
3373         }
3374     }
3375
3376     if (parser->tok != '(') {
3377         parseerror(parser, "expected 'switch' operand in parenthesis");
3378         return false;
3379     }
3380
3381     vec_push(parser->breaks, label);
3382
3383     rv = parse_switch_go(parser, block, out);
3384     if (label)
3385         mem_d(label);
3386     if (vec_last(parser->breaks) != label) {
3387         parseerror(parser, "internal error: label stack corrupted");
3388         rv = false;
3389         ast_delete(*out);
3390         *out = NULL;
3391     }
3392     else {
3393         vec_pop(parser->breaks);
3394     }
3395     return rv;
3396 }
3397
3398 static bool parse_switch_go(parser_t *parser, ast_block *block, ast_expression **out)
3399 {
3400     ast_expression *operand;
3401     ast_value      *opval;
3402     ast_value      *typevar;
3403     ast_switch     *switchnode;
3404     ast_switch_case swcase;
3405
3406     int  cvq;
3407     bool noref, is_static;
3408     uint32_t qflags = 0;
3409
3410     lex_ctx_t ctx = parser_ctx(parser);
3411
3412     (void)block; /* not touching */
3413     (void)opval;
3414
3415     /* parse into the expression */
3416     if (!parser_next(parser)) {
3417         parseerror(parser, "expected switch operand");
3418         return false;
3419     }
3420     /* parse the operand */
3421     operand = parse_expression_leave(parser, false, false, false);
3422     if (!operand)
3423         return false;
3424
3425     switchnode = ast_switch_new(ctx, operand);
3426
3427     /* closing paren */
3428     if (parser->tok != ')') {
3429         ast_delete(switchnode);
3430         parseerror(parser, "expected closing paren after 'switch' operand");
3431         return false;
3432     }
3433
3434     /* parse over the opening paren */
3435     if (!parser_next(parser) || parser->tok != '{') {
3436         ast_delete(switchnode);
3437         parseerror(parser, "expected list of cases");
3438         return false;