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