]> de.git.xonotic.org Git - xonotic/gmqcc.git/blob - parser.c
Use memcmp for comparing doubles
[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;
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 opid2('+','='):
882         case opid2('-','='):
883             if (exprs[0]->expression.vtype != exprs[1]->expression.vtype ||
884                 (exprs[0]->expression.vtype != TYPE_VECTOR && exprs[0]->expression.vtype != TYPE_FLOAT) )
885             {
886                 parseerror(parser, "invalid types used in expression: cannot add or subtract type %s and %s",
887                            type_name[exprs[0]->expression.vtype],
888                            type_name[exprs[1]->expression.vtype]);
889                 return false;
890             }
891             if (ast_istype(exprs[0], ast_entfield))
892                 assignop = type_storep_instr[exprs[0]->expression.vtype];
893             else
894                 assignop = type_store_instr[exprs[0]->expression.vtype];
895             switch (exprs[0]->expression.vtype) {
896                 case TYPE_FLOAT:
897                     out = (ast_expression*)ast_binstore_new(ctx, assignop,
898                                                             (op->id == opid2('+','=') ? INSTR_ADD_F : INSTR_SUB_F),
899                                                             exprs[0], exprs[1]);
900                     break;
901                 case TYPE_VECTOR:
902                     out = (ast_expression*)ast_binstore_new(ctx, assignop,
903                                                             (op->id == opid2('+','=') ? INSTR_ADD_V : INSTR_SUB_V),
904                                                             exprs[0], exprs[1]);
905                     break;
906                 default:
907                     parseerror(parser, "invalid types used in expression: cannot add or subtract type %s and %s",
908                                type_name[exprs[0]->expression.vtype],
909                                type_name[exprs[1]->expression.vtype]);
910                     return false;
911             };
912             break;
913     }
914 #undef NotSameType
915
916     if (!out) {
917         parseerror(parser, "failed to apply operand %s", op->op);
918         return false;
919     }
920
921     DEBUGSHUNTDO(con_out("applied %s\n", op->op));
922     vec_push(sy->out, syexp(ctx, out));
923     return true;
924 }
925
926 static bool parser_close_call(parser_t *parser, shunt *sy)
927 {
928     /* was a function call */
929     ast_expression *fun;
930     ast_call       *call;
931
932     size_t          fid;
933     size_t          paramcount;
934
935     vec_shrinkby(sy->ops, 1);
936     fid = sy->ops[vec_size(sy->ops)].off;
937
938     /* out[fid] is the function
939      * everything above is parameters...
940      * 0 params = nothing
941      * 1 params = ast_expression
942      * more = ast_block
943      */
944
945     if (vec_size(sy->out) < 1 || vec_size(sy->out) <= fid) {
946         parseerror(parser, "internal error: function call needs function and parameter list...");
947         return false;
948     }
949
950     fun = sy->out[fid].out;
951
952     call = ast_call_new(sy->ops[vec_size(sy->ops)].ctx, fun);
953     if (!call) {
954         parseerror(parser, "out of memory");
955         return false;
956     }
957
958     if (fid+1 == vec_size(sy->out)) {
959         /* no arguments */
960         paramcount = 0;
961     } else if (fid+2 == vec_size(sy->out)) {
962         ast_block *params;
963         vec_shrinkby(sy->out, 1);
964         params = sy->out[vec_size(sy->out)].block;
965         if (!params) {
966             /* 1 param */
967             paramcount = 1;
968             vec_push(call->params, sy->out[vec_size(sy->out)].out);
969         } else {
970             paramcount = vec_size(params->exprs);
971             call->params = params->exprs;
972             params->exprs = NULL;
973             ast_delete(params);
974         }
975         if (!ast_call_check_types(call))
976             parser->errors++;
977     } else {
978         parseerror(parser, "invalid function call");
979         return false;
980     }
981
982     /* overwrite fid, the function, with a call */
983     sy->out[fid] = syexp(call->expression.node.context, (ast_expression*)call);
984
985     if (fun->expression.vtype != TYPE_FUNCTION) {
986         parseerror(parser, "not a function (%s)", type_name[fun->expression.vtype]);
987         return false;
988     }
989
990     if (!fun->expression.next) {
991         parseerror(parser, "could not determine function return type");
992         return false;
993     } else {
994         if (vec_size(fun->expression.params) != paramcount &&
995             !(fun->expression.variadic &&
996               vec_size(fun->expression.params) < paramcount))
997         {
998             ast_value *fval;
999             const char *fewmany = (vec_size(fun->expression.params) > paramcount) ? "few" : "many";
1000
1001             fval = (ast_istype(fun, ast_value) ? ((ast_value*)fun) : NULL);
1002             if (opts_standard == COMPILER_GMQCC)
1003             {
1004                 if (fval)
1005                     parseerror(parser, "too %s parameters for call to %s: expected %i, got %i\n"
1006                                " -> `%s` has been declared here: %s:%i",
1007                                fewmany, fval->name, (int)vec_size(fun->expression.params), (int)paramcount,
1008                                fval->name, ast_ctx(fun).file, (int)ast_ctx(fun).line);
1009                 else
1010                     parseerror(parser, "too %s parameters for function call: expected %i, got %i\n"
1011                                " -> `%s` has been declared here: %s:%i",
1012                                fewmany, fval->name, (int)vec_size(fun->expression.params), (int)paramcount,
1013                                fval->name, ast_ctx(fun).file, (int)ast_ctx(fun).line);
1014                 return false;
1015             }
1016             else
1017             {
1018                 if (fval)
1019                     return !parsewarning(parser, WARN_TOO_FEW_PARAMETERS,
1020                                          "too %s parameters for call to %s: expected %i, got %i\n"
1021                                          " -> `%s` has been declared here: %s:%i",
1022                                          fewmany, fval->name, (int)vec_size(fun->expression.params), (int)paramcount,
1023                                          fval->name, ast_ctx(fun).file, (int)ast_ctx(fun).line);
1024                 else
1025                     return !parsewarning(parser, WARN_TOO_FEW_PARAMETERS,
1026                                          "too %s parameters for function call: expected %i, got %i\n"
1027                                          " -> `%s` has been declared here: %s:%i",
1028                                          fewmany, fval->name, (int)vec_size(fun->expression.params), (int)paramcount,
1029                                          fval->name, ast_ctx(fun).file, (int)ast_ctx(fun).line);
1030             }
1031         }
1032     }
1033
1034     return true;
1035 }
1036
1037 static bool parser_close_paren(parser_t *parser, shunt *sy, bool functions_only)
1038 {
1039     if (!vec_size(sy->ops)) {
1040         parseerror(parser, "unmatched closing paren");
1041         return false;
1042     }
1043     /* this would for bit a + (x) because there are no operators inside (x)
1044     if (sy->ops[vec_size(sy->ops)-1].paren == 1) {
1045         parseerror(parser, "empty parenthesis expression");
1046         return false;
1047     }
1048     */
1049     while (vec_size(sy->ops)) {
1050         if (sy->ops[vec_size(sy->ops)-1].paren == SY_PAREN_FUNC) {
1051             if (!parser_close_call(parser, sy))
1052                 return false;
1053             break;
1054         }
1055         if (sy->ops[vec_size(sy->ops)-1].paren == SY_PAREN_EXPR) {
1056             vec_shrinkby(sy->ops, 1);
1057             return !functions_only;
1058         }
1059         if (sy->ops[vec_size(sy->ops)-1].paren == SY_PAREN_INDEX) {
1060             if (functions_only)
1061                 return false;
1062             /* pop off the parenthesis */
1063             vec_shrinkby(sy->ops, 1);
1064             /* then apply the index operator */
1065             if (!parser_sy_pop(parser, sy))
1066                 return false;
1067             return true;
1068         }
1069         if (!parser_sy_pop(parser, sy))
1070             return false;
1071     }
1072     return true;
1073 }
1074
1075 static void parser_reclassify_token(parser_t *parser)
1076 {
1077     size_t i;
1078     for (i = 0; i < operator_count; ++i) {
1079         if (!strcmp(parser_tokval(parser), operators[i].op)) {
1080             parser->tok = TOKEN_OPERATOR;
1081             return;
1082         }
1083     }
1084 }
1085
1086 static ast_expression* parse_expression_leave(parser_t *parser, bool stopatcomma)
1087 {
1088     ast_expression *expr = NULL;
1089     shunt sy;
1090     bool wantop = false;
1091     bool gotmemberof = false;
1092
1093     /* count the parens because an if starts with one, so the
1094      * end of a condition is an unmatched closing paren
1095      */
1096     int parens = 0;
1097     int ternaries = 0;
1098
1099     sy.out = NULL;
1100     sy.ops = NULL;
1101
1102     parser->lex->flags.noops = false;
1103
1104     parser_reclassify_token(parser);
1105
1106     while (true)
1107     {
1108         if (gotmemberof)
1109             gotmemberof = false;
1110         else
1111             parser->memberof = 0;
1112
1113         if (parser->tok == TOKEN_IDENT)
1114         {
1115             ast_expression *var;
1116             if (wantop) {
1117                 parseerror(parser, "expected operator or end of statement");
1118                 goto onerr;
1119             }
1120             wantop = true;
1121             /* variable */
1122             if (opts_standard == COMPILER_GMQCC)
1123             {
1124                 if (parser->memberof == TYPE_ENTITY) {
1125                     /* still get vars first since there could be a fieldpointer */
1126                     var = parser_find_var(parser, parser_tokval(parser));
1127                     if (!var)
1128                         var = parser_find_field(parser, parser_tokval(parser));
1129                 }
1130                 else if (parser->memberof == TYPE_VECTOR)
1131                 {
1132                     parseerror(parser, "TODO: implement effective vector member access");
1133                     goto onerr;
1134                 }
1135                 else if (parser->memberof) {
1136                     parseerror(parser, "namespace for member not found");
1137                     goto onerr;
1138                 }
1139                 else
1140                     var = parser_find_var(parser, parser_tokval(parser));
1141             } else {
1142                 var = parser_find_var(parser, parser_tokval(parser));
1143                 if (!var)
1144                     var = parser_find_field(parser, parser_tokval(parser));
1145             }
1146             if (!var) {
1147                 parseerror(parser, "unexpected ident: %s", parser_tokval(parser));
1148                 goto onerr;
1149             }
1150             if (ast_istype(var, ast_value))
1151                 ((ast_value*)var)->uses++;
1152             vec_push(sy.out, syexp(parser_ctx(parser), var));
1153             DEBUGSHUNTDO(con_out("push %s\n", parser_tokval(parser)));
1154         }
1155         else if (parser->tok == TOKEN_FLOATCONST) {
1156             ast_value *val;
1157             if (wantop) {
1158                 parseerror(parser, "expected operator or end of statement, got constant");
1159                 goto onerr;
1160             }
1161             wantop = true;
1162             val = parser_const_float(parser, (parser_token(parser)->constval.f));
1163             if (!val)
1164                 return false;
1165             vec_push(sy.out, syexp(parser_ctx(parser), (ast_expression*)val));
1166             DEBUGSHUNTDO(con_out("push %g\n", parser_token(parser)->constval.f));
1167         }
1168         else if (parser->tok == TOKEN_INTCONST) {
1169             ast_value *val;
1170             if (wantop) {
1171                 parseerror(parser, "expected operator or end of statement, got constant");
1172                 goto onerr;
1173             }
1174             wantop = true;
1175             val = parser_const_float(parser, (double)(parser_token(parser)->constval.i));
1176             if (!val)
1177                 return false;
1178             vec_push(sy.out, syexp(parser_ctx(parser), (ast_expression*)val));
1179             DEBUGSHUNTDO(con_out("push %i\n", parser_token(parser)->constval.i));
1180         }
1181         else if (parser->tok == TOKEN_STRINGCONST) {
1182             ast_value *val;
1183             if (wantop) {
1184                 parseerror(parser, "expected operator or end of statement, got constant");
1185                 goto onerr;
1186             }
1187             wantop = true;
1188             val = parser_const_string(parser, parser_tokval(parser));
1189             if (!val)
1190                 return false;
1191             vec_push(sy.out, syexp(parser_ctx(parser), (ast_expression*)val));
1192             DEBUGSHUNTDO(con_out("push string\n"));
1193         }
1194         else if (parser->tok == TOKEN_VECTORCONST) {
1195             ast_value *val;
1196             if (wantop) {
1197                 parseerror(parser, "expected operator or end of statement, got constant");
1198                 goto onerr;
1199             }
1200             wantop = true;
1201             val = parser_const_vector(parser, parser_token(parser)->constval.v);
1202             if (!val)
1203                 return false;
1204             vec_push(sy.out, syexp(parser_ctx(parser), (ast_expression*)val));
1205             DEBUGSHUNTDO(con_out("push '%g %g %g'\n",
1206                                 parser_token(parser)->constval.v.x,
1207                                 parser_token(parser)->constval.v.y,
1208                                 parser_token(parser)->constval.v.z));
1209         }
1210         else if (parser->tok == '(') {
1211             parseerror(parser, "internal error: '(' should be classified as operator");
1212             goto onerr;
1213         }
1214         else if (parser->tok == '[') {
1215             parseerror(parser, "internal error: '[' should be classified as operator");
1216             goto onerr;
1217         }
1218         else if (parser->tok == ')') {
1219             if (wantop) {
1220                 DEBUGSHUNTDO(con_out("do[op] )\n"));
1221                 --parens;
1222                 if (parens < 0)
1223                     break;
1224                 /* we do expect an operator next */
1225                 /* closing an opening paren */
1226                 if (!parser_close_paren(parser, &sy, false))
1227                     goto onerr;
1228             } else {
1229                 DEBUGSHUNTDO(con_out("do[nop] )\n"));
1230                 --parens;
1231                 if (parens < 0)
1232                     break;
1233                 /* allowed for function calls */
1234                 if (!parser_close_paren(parser, &sy, true))
1235                     goto onerr;
1236             }
1237             wantop = true;
1238         }
1239         else if (parser->tok == ']') {
1240             if (!wantop)
1241                 parseerror(parser, "operand expected");
1242             --parens;
1243             if (parens < 0)
1244                 break;
1245             if (!parser_close_paren(parser, &sy, false))
1246                 goto onerr;
1247             wantop = true;
1248         }
1249         else if (parser->tok != TOKEN_OPERATOR) {
1250             if (wantop) {
1251                 parseerror(parser, "expected operator or end of statement");
1252                 goto onerr;
1253             }
1254             break;
1255         }
1256         else
1257         {
1258             /* classify the operator */
1259             /* TODO: suffix operators */
1260             const oper_info *op;
1261             const oper_info *olast = NULL;
1262             size_t o;
1263             for (o = 0; o < operator_count; ++o) {
1264                 if ((!(operators[o].flags & OP_PREFIX) == wantop) &&
1265                     !(operators[o].flags & OP_SUFFIX) && /* remove this */
1266                     !strcmp(parser_tokval(parser), operators[o].op))
1267                 {
1268                     break;
1269                 }
1270             }
1271             if (o == operator_count) {
1272                 /* no operator found... must be the end of the statement */
1273                 break;
1274             }
1275             /* found an operator */
1276             op = &operators[o];
1277
1278             /* when declaring variables, a comma starts a new variable */
1279             if (op->id == opid1(',') && !parens && stopatcomma) {
1280                 /* fixup the token */
1281                 parser->tok = ',';
1282                 break;
1283             }
1284
1285             /* a colon without a pervious question mark cannot be a ternary */
1286             if (!ternaries && op->id == opid2(':','?')) {
1287                 parser->tok = ':';
1288                 break;
1289             }
1290
1291             if (vec_size(sy.ops) && !vec_last(sy.ops).paren)
1292                 olast = &operators[vec_last(sy.ops).etype-1];
1293
1294             while (olast && (
1295                     (op->prec < olast->prec) ||
1296                     (op->assoc == ASSOC_LEFT && op->prec <= olast->prec) ) )
1297             {
1298                 if (!parser_sy_pop(parser, &sy))
1299                     goto onerr;
1300                 if (vec_size(sy.ops) && !vec_last(sy.ops).paren)
1301                     olast = &operators[vec_last(sy.ops).etype-1];
1302                 else
1303                     olast = NULL;
1304             }
1305
1306             if (op->id == opid1('.') && opts_standard == COMPILER_GMQCC) {
1307                 /* for gmqcc standard: open up the namespace of the previous type */
1308                 ast_expression *prevex = vec_last(sy.out).out;
1309                 if (!prevex) {
1310                     parseerror(parser, "unexpected member operator");
1311                     goto onerr;
1312                 }
1313                 if (prevex->expression.vtype == TYPE_ENTITY)
1314                     parser->memberof = TYPE_ENTITY;
1315                 else if (prevex->expression.vtype == TYPE_VECTOR)
1316                     parser->memberof = TYPE_VECTOR;
1317                 else {
1318                     parseerror(parser, "type error: type has no members");
1319                     goto onerr;
1320                 }
1321                 gotmemberof = true;
1322             }
1323
1324             if (op->id == opid1('(')) {
1325                 if (wantop) {
1326                     size_t sycount = vec_size(sy.out);
1327                     DEBUGSHUNTDO(con_out("push [op] (\n"));
1328                     ++parens;
1329                     /* we expected an operator, this is the function-call operator */
1330                     vec_push(sy.ops, syparen(parser_ctx(parser), SY_PAREN_FUNC, sycount-1));
1331                 } else {
1332                     ++parens;
1333                     vec_push(sy.ops, syparen(parser_ctx(parser), SY_PAREN_EXPR, 0));
1334                     DEBUGSHUNTDO(con_out("push [nop] (\n"));
1335                 }
1336                 wantop = false;
1337             } else if (op->id == opid1('[')) {
1338                 if (!wantop) {
1339                     parseerror(parser, "unexpected array subscript");
1340                     goto onerr;
1341                 }
1342                 ++parens;
1343                 /* push both the operator and the paren, this makes life easier */
1344                 vec_push(sy.ops, syop(parser_ctx(parser), op));
1345                 vec_push(sy.ops, syparen(parser_ctx(parser), SY_PAREN_INDEX, 0));
1346                 wantop = false;
1347             } else if (op->id == opid2('?',':')) {
1348                 wantop = false;
1349                 vec_push(sy.ops, syop(parser_ctx(parser), op));
1350                 wantop = false;
1351                 --ternaries;
1352             } else if (op->id == opid2(':','?')) {
1353                 /* we don't push this operator */
1354                 wantop = false;
1355                 ++ternaries;
1356             } else {
1357                 DEBUGSHUNTDO(con_out("push operator %s\n", op->op));
1358                 vec_push(sy.ops, syop(parser_ctx(parser), op));
1359                 wantop = false;
1360             }
1361         }
1362         if (!parser_next(parser)) {
1363             goto onerr;
1364         }
1365         if (parser->tok == ';' ||
1366             (!parens && parser->tok == ']'))
1367         {
1368             break;
1369         }
1370     }
1371
1372     while (vec_size(sy.ops)) {
1373         if (!parser_sy_pop(parser, &sy))
1374             goto onerr;
1375     }
1376
1377     parser->lex->flags.noops = true;
1378     if (!vec_size(sy.out)) {
1379         parseerror(parser, "empty expression");
1380         expr = NULL;
1381     } else
1382         expr = sy.out[0].out;
1383     vec_free(sy.out);
1384     vec_free(sy.ops);
1385     DEBUGSHUNTDO(con_out("shunt done\n"));
1386     return expr;
1387
1388 onerr:
1389     parser->lex->flags.noops = true;
1390     vec_free(sy.out);
1391     vec_free(sy.ops);
1392     return NULL;
1393 }
1394
1395 static ast_expression* parse_expression(parser_t *parser, bool stopatcomma)
1396 {
1397     ast_expression *e = parse_expression_leave(parser, stopatcomma);
1398     if (!e)
1399         return NULL;
1400     if (!parser_next(parser)) {
1401         ast_delete(e);
1402         return NULL;
1403     }
1404     return e;
1405 }
1406
1407 static bool parse_if(parser_t *parser, ast_block *block, ast_expression **out)
1408 {
1409     ast_ifthen *ifthen;
1410     ast_expression *cond, *ontrue, *onfalse = NULL;
1411     bool ifnot = false;
1412
1413     lex_ctx ctx = parser_ctx(parser);
1414
1415     (void)block; /* not touching */
1416
1417     /* skip the 'if', parse an optional 'not' and check for an opening paren */
1418     if (!parser_next(parser)) {
1419         parseerror(parser, "expected condition or 'not'");
1420         return false;
1421     }
1422     if (parser->tok == TOKEN_KEYWORD && !strcmp(parser_tokval(parser), "not")) {
1423         ifnot = true;
1424         if (!parser_next(parser)) {
1425             parseerror(parser, "expected condition in parenthesis");
1426             return false;
1427         }
1428     }
1429     if (parser->tok != '(') {
1430         parseerror(parser, "expected 'if' condition in parenthesis");
1431         return false;
1432     }
1433     /* parse into the expression */
1434     if (!parser_next(parser)) {
1435         parseerror(parser, "expected 'if' condition after opening paren");
1436         return false;
1437     }
1438     /* parse the condition */
1439     cond = parse_expression_leave(parser, false);
1440     if (!cond)
1441         return false;
1442     /* closing paren */
1443     if (parser->tok != ')') {
1444         parseerror(parser, "expected closing paren after 'if' condition");
1445         ast_delete(cond);
1446         return false;
1447     }
1448     /* parse into the 'then' branch */
1449     if (!parser_next(parser)) {
1450         parseerror(parser, "expected statement for on-true branch of 'if'");
1451         ast_delete(cond);
1452         return false;
1453     }
1454     ontrue = parse_statement_or_block(parser);
1455     if (!ontrue) {
1456         ast_delete(cond);
1457         return false;
1458     }
1459     /* check for an else */
1460     if (!strcmp(parser_tokval(parser), "else")) {
1461         /* parse into the 'else' branch */
1462         if (!parser_next(parser)) {
1463             parseerror(parser, "expected on-false branch after 'else'");
1464             ast_delete(ontrue);
1465             ast_delete(cond);
1466             return false;
1467         }
1468         onfalse = parse_statement_or_block(parser);
1469         if (!onfalse) {
1470             ast_delete(ontrue);
1471             ast_delete(cond);
1472             return false;
1473         }
1474     }
1475
1476     if (ifnot)
1477         ifthen = ast_ifthen_new(ctx, cond, onfalse, ontrue);
1478     else
1479         ifthen = ast_ifthen_new(ctx, cond, ontrue, onfalse);
1480     *out = (ast_expression*)ifthen;
1481     return true;
1482 }
1483
1484 static bool parse_while(parser_t *parser, ast_block *block, ast_expression **out)
1485 {
1486     ast_loop *aloop;
1487     ast_expression *cond, *ontrue;
1488
1489     lex_ctx ctx = parser_ctx(parser);
1490
1491     (void)block; /* not touching */
1492
1493     /* skip the 'while' and check for opening paren */
1494     if (!parser_next(parser) || parser->tok != '(') {
1495         parseerror(parser, "expected 'while' condition in parenthesis");
1496         return false;
1497     }
1498     /* parse into the expression */
1499     if (!parser_next(parser)) {
1500         parseerror(parser, "expected 'while' condition after opening paren");
1501         return false;
1502     }
1503     /* parse the condition */
1504     cond = parse_expression_leave(parser, false);
1505     if (!cond)
1506         return false;
1507     /* closing paren */
1508     if (parser->tok != ')') {
1509         parseerror(parser, "expected closing paren after 'while' condition");
1510         ast_delete(cond);
1511         return false;
1512     }
1513     /* parse into the 'then' branch */
1514     if (!parser_next(parser)) {
1515         parseerror(parser, "expected while-loop body");
1516         ast_delete(cond);
1517         return false;
1518     }
1519     ontrue = parse_statement_or_block(parser);
1520     if (!ontrue) {
1521         ast_delete(cond);
1522         return false;
1523     }
1524
1525     aloop = ast_loop_new(ctx, NULL, cond, NULL, NULL, ontrue);
1526     *out = (ast_expression*)aloop;
1527     return true;
1528 }
1529
1530 static bool parse_dowhile(parser_t *parser, ast_block *block, ast_expression **out)
1531 {
1532     ast_loop *aloop;
1533     ast_expression *cond, *ontrue;
1534
1535     lex_ctx ctx = parser_ctx(parser);
1536
1537     (void)block; /* not touching */
1538
1539     /* skip the 'do' and get the body */
1540     if (!parser_next(parser)) {
1541         parseerror(parser, "expected loop body");
1542         return false;
1543     }
1544     ontrue = parse_statement_or_block(parser);
1545     if (!ontrue)
1546         return false;
1547
1548     /* expect the "while" */
1549     if (parser->tok != TOKEN_KEYWORD ||
1550         strcmp(parser_tokval(parser), "while"))
1551     {
1552         parseerror(parser, "expected 'while' and condition");
1553         ast_delete(ontrue);
1554         return false;
1555     }
1556
1557     /* skip the 'while' and check for opening paren */
1558     if (!parser_next(parser) || parser->tok != '(') {
1559         parseerror(parser, "expected 'while' condition in parenthesis");
1560         ast_delete(ontrue);
1561         return false;
1562     }
1563     /* parse into the expression */
1564     if (!parser_next(parser)) {
1565         parseerror(parser, "expected 'while' condition after opening paren");
1566         ast_delete(ontrue);
1567         return false;
1568     }
1569     /* parse the condition */
1570     cond = parse_expression_leave(parser, false);
1571     if (!cond)
1572         return false;
1573     /* closing paren */
1574     if (parser->tok != ')') {
1575         parseerror(parser, "expected closing paren after 'while' condition");
1576         ast_delete(ontrue);
1577         ast_delete(cond);
1578         return false;
1579     }
1580     /* parse on */
1581     if (!parser_next(parser) || parser->tok != ';') {
1582         parseerror(parser, "expected semicolon after condition");
1583         ast_delete(ontrue);
1584         ast_delete(cond);
1585         return false;
1586     }
1587
1588     if (!parser_next(parser)) {
1589         parseerror(parser, "parse error");
1590         ast_delete(ontrue);
1591         ast_delete(cond);
1592         return false;
1593     }
1594
1595     aloop = ast_loop_new(ctx, NULL, NULL, cond, NULL, ontrue);
1596     *out = (ast_expression*)aloop;
1597     return true;
1598 }
1599
1600 static bool parse_for(parser_t *parser, ast_block *block, ast_expression **out)
1601 {
1602     ast_loop *aloop;
1603     ast_expression *initexpr, *cond, *increment, *ontrue;
1604     size_t oldblocklocal;
1605     bool   retval = true;
1606
1607     lex_ctx ctx = parser_ctx(parser);
1608
1609     oldblocklocal = parser->blocklocal;
1610     parser->blocklocal = vec_size(parser->locals);
1611
1612     initexpr  = NULL;
1613     cond      = NULL;
1614     increment = NULL;
1615     ontrue    = NULL;
1616
1617     /* skip the 'while' and check for opening paren */
1618     if (!parser_next(parser) || parser->tok != '(') {
1619         parseerror(parser, "expected 'for' expressions in parenthesis");
1620         goto onerr;
1621     }
1622     /* parse into the expression */
1623     if (!parser_next(parser)) {
1624         parseerror(parser, "expected 'for' initializer after opening paren");
1625         goto onerr;
1626     }
1627
1628     if (parser->tok == TOKEN_TYPENAME) {
1629         if (opts_standard != COMPILER_GMQCC) {
1630             if (parsewarning(parser, WARN_EXTENSIONS,
1631                              "current standard does not allow variable declarations in for-loop initializers"))
1632                 goto onerr;
1633         }
1634
1635         parseerror(parser, "TODO: assignment of new variables to be non-const");
1636         goto onerr;
1637         if (!parse_variable(parser, block, true))
1638             goto onerr;
1639     }
1640     else if (parser->tok != ';')
1641     {
1642         initexpr = parse_expression_leave(parser, false);
1643         if (!initexpr)
1644             goto onerr;
1645     }
1646
1647     /* move on to condition */
1648     if (parser->tok != ';') {
1649         parseerror(parser, "expected semicolon after for-loop initializer");
1650         goto onerr;
1651     }
1652     if (!parser_next(parser)) {
1653         parseerror(parser, "expected for-loop condition");
1654         goto onerr;
1655     }
1656
1657     /* parse the condition */
1658     if (parser->tok != ';') {
1659         cond = parse_expression_leave(parser, false);
1660         if (!cond)
1661             goto onerr;
1662     }
1663
1664     /* move on to incrementor */
1665     if (parser->tok != ';') {
1666         parseerror(parser, "expected semicolon after for-loop initializer");
1667         goto onerr;
1668     }
1669     if (!parser_next(parser)) {
1670         parseerror(parser, "expected for-loop condition");
1671         goto onerr;
1672     }
1673
1674     /* parse the incrementor */
1675     if (parser->tok != ')') {
1676         increment = parse_expression_leave(parser, false);
1677         if (!increment)
1678             goto onerr;
1679         if (!ast_istype(increment, ast_store) &&
1680             !ast_istype(increment, ast_call) &&
1681             !ast_istype(increment, ast_binstore))
1682         {
1683             if (genwarning(ast_ctx(increment), WARN_EFFECTLESS_STATEMENT, "statement has no effect"))
1684                 goto onerr;
1685         }
1686     }
1687
1688     /* closing paren */
1689     if (parser->tok != ')') {
1690         parseerror(parser, "expected closing paren after 'for-loop' incrementor");
1691         goto onerr;
1692     }
1693     /* parse into the 'then' branch */
1694     if (!parser_next(parser)) {
1695         parseerror(parser, "expected for-loop body");
1696         goto onerr;
1697     }
1698     ontrue = parse_statement_or_block(parser);
1699     if (!ontrue) {
1700         goto onerr;
1701     }
1702
1703     aloop = ast_loop_new(ctx, initexpr, cond, NULL, increment, ontrue);
1704     *out = (ast_expression*)aloop;
1705
1706     while (vec_size(parser->locals) > parser->blocklocal)
1707         retval = retval && parser_pop_local(parser);
1708     parser->blocklocal = oldblocklocal;
1709     return retval;
1710 onerr:
1711     if (initexpr)  ast_delete(initexpr);
1712     if (cond)      ast_delete(cond);
1713     if (increment) ast_delete(increment);
1714     while (vec_size(parser->locals) > parser->blocklocal)
1715         (void)!parser_pop_local(parser);
1716     parser->blocklocal = oldblocklocal;
1717     return false;
1718 }
1719
1720 static bool parse_return(parser_t *parser, ast_block *block, ast_expression **out)
1721 {
1722     ast_expression *exp = NULL;
1723     ast_return     *ret = NULL;
1724     ast_value      *expected = parser->function->vtype;
1725
1726     (void)block; /* not touching */
1727
1728     if (!parser_next(parser)) {
1729         parseerror(parser, "expected return expression");
1730         return false;
1731     }
1732
1733     if (parser->tok != ';') {
1734         exp = parse_expression(parser, false);
1735         if (!exp)
1736             return false;
1737
1738         if (exp->expression.vtype != expected->expression.next->expression.vtype) {
1739             parseerror(parser, "return with invalid expression");
1740         }
1741
1742         ret = ast_return_new(exp->expression.node.context, exp);
1743         if (!ret) {
1744             ast_delete(exp);
1745             return false;
1746         }
1747     } else {
1748         if (!parser_next(parser))
1749             parseerror(parser, "parse error");
1750         if (expected->expression.next->expression.vtype != TYPE_VOID) {
1751             if (opts_standard != COMPILER_GMQCC)
1752                 (void)!parsewarning(parser, WARN_MISSING_RETURN_VALUES, "return without value");
1753             else
1754                 parseerror(parser, "return without value");
1755         }
1756         ret = ast_return_new(parser_ctx(parser), NULL);
1757     }
1758     *out = (ast_expression*)ret;
1759     return true;
1760 }
1761
1762 static bool parse_break_continue(parser_t *parser, ast_block *block, ast_expression **out, bool is_continue)
1763 {
1764     lex_ctx ctx = parser_ctx(parser);
1765
1766     (void)block; /* not touching */
1767
1768     if (!parser_next(parser) || parser->tok != ';') {
1769         parseerror(parser, "expected semicolon");
1770         return false;
1771     }
1772
1773     if (!parser_next(parser))
1774         parseerror(parser, "parse error");
1775
1776     *out = (ast_expression*)ast_breakcont_new(ctx, is_continue);
1777     return true;
1778 }
1779
1780 static bool parse_switch(parser_t *parser, ast_block *block, ast_expression **out)
1781 {
1782     ast_expression *operand;
1783     ast_value      *opval;
1784     ast_switch     *switchnode;
1785     ast_switch_case swcase;
1786
1787     lex_ctx ctx = parser_ctx(parser);
1788
1789     (void)block; /* not touching */
1790
1791     /* parse over the opening paren */
1792     if (!parser_next(parser) || parser->tok != '(') {
1793         parseerror(parser, "expected switch operand in parenthesis");
1794         return false;
1795     }
1796
1797     /* parse into the expression */
1798     if (!parser_next(parser)) {
1799         parseerror(parser, "expected switch operand");
1800         return false;
1801     }
1802     /* parse the operand */
1803     operand = parse_expression_leave(parser, false);
1804     if (!operand)
1805         return false;
1806
1807     if (!OPTS_FLAG(RELAXED_SWITCH)) {
1808         opval = (ast_value*)operand;
1809         if (!ast_istype(operand, ast_value) || !opval->isconst) {
1810             parseerror(parser, "case on non-constant values need to be explicitly enabled via -frelaxed-switch");
1811             ast_unref(operand);
1812             return false;
1813         }
1814     }
1815
1816     switchnode = ast_switch_new(ctx, operand);
1817
1818     /* closing paren */
1819     if (parser->tok != ')') {
1820         ast_delete(switchnode);
1821         parseerror(parser, "expected closing paren after 'switch' operand");
1822         return false;
1823     }
1824
1825     /* parse over the opening paren */
1826     if (!parser_next(parser) || parser->tok != '{') {
1827         ast_delete(switchnode);
1828         parseerror(parser, "expected list of cases");
1829         return false;
1830     }
1831
1832     if (!parser_next(parser)) {
1833         ast_delete(switchnode);
1834         parseerror(parser, "expected 'case' or 'default'");
1835         return false;
1836     }
1837
1838     /* case list! */
1839     while (parser->tok != '}') {
1840         ast_block *caseblock;
1841
1842         if (parser->tok != TOKEN_KEYWORD) {
1843             ast_delete(switchnode);
1844             parseerror(parser, "expected 'case' or 'default'");
1845             return false;
1846         }
1847         if (!strcmp(parser_tokval(parser), "case")) {
1848             if (!parser_next(parser)) {
1849                 ast_delete(switchnode);
1850                 parseerror(parser, "expected expression for case");
1851                 return false;
1852             }
1853             swcase.value = parse_expression_leave(parser, false);
1854             if (!swcase.value) {
1855                 ast_delete(switchnode);
1856                 parseerror(parser, "expected expression for case");
1857                 return false;
1858             }
1859         }
1860         else if (!strcmp(parser_tokval(parser), "default")) {
1861             swcase.value = NULL;
1862             if (!parser_next(parser)) {
1863                 ast_delete(switchnode);
1864                 parseerror(parser, "expected colon");
1865                 return false;
1866             }
1867         }
1868
1869         /* Now the colon and body */
1870         if (parser->tok != ':') {
1871             if (swcase.value) ast_unref(swcase.value);
1872             ast_delete(switchnode);
1873             parseerror(parser, "expected colon");
1874             return false;
1875         }
1876
1877         if (!parser_next(parser)) {
1878             if (swcase.value) ast_unref(swcase.value);
1879             ast_delete(switchnode);
1880             parseerror(parser, "expected statements or case");
1881             return false;
1882         }
1883         caseblock = ast_block_new(parser_ctx(parser));
1884         if (!caseblock) {
1885             if (swcase.value) ast_unref(swcase.value);
1886             ast_delete(switchnode);
1887             return false;
1888         }
1889         swcase.code = (ast_expression*)caseblock;
1890         vec_push(switchnode->cases, swcase);
1891         while (true) {
1892             ast_expression *expr;
1893             if (parser->tok == '}')
1894                 break;
1895             if (parser->tok == TOKEN_KEYWORD) {
1896                 if (!strcmp(parser_tokval(parser), "case") ||
1897                     !strcmp(parser_tokval(parser), "default"))
1898                 {
1899                     break;
1900                 }
1901             }
1902             if (!parse_statement(parser, caseblock, &expr, true)) {
1903                 ast_delete(switchnode);
1904                 return false;
1905             }
1906             if (!expr)
1907                 continue;
1908             vec_push(caseblock->exprs, expr);
1909         }
1910     }
1911
1912     /* closing paren */
1913     if (parser->tok != '}') {
1914         ast_delete(switchnode);
1915         parseerror(parser, "expected closing paren of case list");
1916         return false;
1917     }
1918     if (!parser_next(parser)) {
1919         ast_delete(switchnode);
1920         parseerror(parser, "parse error after switch");
1921         return false;
1922     }
1923     *out = (ast_expression*)switchnode;
1924     return true;
1925 }
1926
1927 static bool parse_statement(parser_t *parser, ast_block *block, ast_expression **out, bool allow_cases)
1928 {
1929     if (parser->tok == TOKEN_TYPENAME || parser->tok == '.')
1930     {
1931         /* local variable */
1932         if (!block) {
1933             parseerror(parser, "cannot declare a variable from here");
1934             return false;
1935         }
1936         if (opts_standard == COMPILER_QCC) {
1937             if (parsewarning(parser, WARN_EXTENSIONS, "missing 'local' keyword when declaring a local variable"))
1938                 return false;
1939         }
1940         if (!parse_variable(parser, block, false))
1941             return false;
1942         *out = NULL;
1943         return true;
1944     }
1945     else if (parser->tok == TOKEN_KEYWORD)
1946     {
1947         if (!strcmp(parser_tokval(parser), "local"))
1948         {
1949             if (!block) {
1950                 parseerror(parser, "cannot declare a local variable here");
1951                 return false;
1952             }
1953             if (!parser_next(parser)) {
1954                 parseerror(parser, "expected variable declaration");
1955                 return false;
1956             }
1957             if (!parse_variable(parser, block, true))
1958                 return false;
1959             *out = NULL;
1960             return true;
1961         }
1962         else if (!strcmp(parser_tokval(parser), "return"))
1963         {
1964             return parse_return(parser, block, out);
1965         }
1966         else if (!strcmp(parser_tokval(parser), "if"))
1967         {
1968             return parse_if(parser, block, out);
1969         }
1970         else if (!strcmp(parser_tokval(parser), "while"))
1971         {
1972             return parse_while(parser, block, out);
1973         }
1974         else if (!strcmp(parser_tokval(parser), "do"))
1975         {
1976             return parse_dowhile(parser, block, out);
1977         }
1978         else if (!strcmp(parser_tokval(parser), "for"))
1979         {
1980             if (opts_standard == COMPILER_QCC) {
1981                 if (parsewarning(parser, WARN_EXTENSIONS, "for loops are not recognized in the original Quake C standard, to enable try an alternate standard --std=?"))
1982                     return false;
1983             }
1984             return parse_for(parser, block, out);
1985         }
1986         else if (!strcmp(parser_tokval(parser), "break"))
1987         {
1988             return parse_break_continue(parser, block, out, false);
1989         }
1990         else if (!strcmp(parser_tokval(parser), "continue"))
1991         {
1992             return parse_break_continue(parser, block, out, true);
1993         }
1994         else if (!strcmp(parser_tokval(parser), "switch"))
1995         {
1996             return parse_switch(parser, block, out);
1997         }
1998         else if (!strcmp(parser_tokval(parser), "case") ||
1999                  !strcmp(parser_tokval(parser), "default"))
2000         {
2001             if (!allow_cases) {
2002                 parseerror(parser, "unexpected 'case' label");
2003                 return false;
2004             }
2005             return true;
2006         }
2007         parseerror(parser, "Unexpected keyword");
2008         return false;
2009     }
2010     else if (parser->tok == '{')
2011     {
2012         ast_block *inner;
2013         inner = parse_block(parser, false);
2014         if (!inner)
2015             return false;
2016         *out = (ast_expression*)inner;
2017         return true;
2018     }
2019     else
2020     {
2021         ast_expression *exp = parse_expression(parser, false);
2022         if (!exp)
2023             return false;
2024         *out = exp;
2025         if (!ast_istype(exp, ast_store) &&
2026             !ast_istype(exp, ast_call) &&
2027             !ast_istype(exp, ast_binstore))
2028         {
2029             if (genwarning(ast_ctx(exp), WARN_EFFECTLESS_STATEMENT, "statement has no effect"))
2030                 return false;
2031         }
2032         return true;
2033     }
2034 }
2035
2036 static bool GMQCC_WARN parser_pop_local(parser_t *parser)
2037 {
2038     bool rv = true;
2039     varentry_t *ve;
2040
2041     ve = &vec_last(parser->locals);
2042     if (!parser->errors) {
2043         if (ast_istype(ve->var, ast_value) && !(((ast_value*)(ve->var))->uses)) {
2044             if (parsewarning(parser, WARN_UNUSED_VARIABLE, "unused variable: `%s`", ve->name))
2045                 rv = false;
2046         }
2047     }
2048     mem_d(ve->name);
2049     vec_pop(parser->locals);
2050     return rv;
2051 }
2052
2053 static bool parse_block_into(parser_t *parser, ast_block *block, bool warnreturn)
2054 {
2055     size_t oldblocklocal;
2056     bool   retval = true;
2057
2058     oldblocklocal = parser->blocklocal;
2059     parser->blocklocal = vec_size(parser->locals);
2060
2061     if (!parser_next(parser)) { /* skip the '{' */
2062         parseerror(parser, "expected function body");
2063         goto cleanup;
2064     }
2065
2066     while (parser->tok != TOKEN_EOF && parser->tok < TOKEN_ERROR)
2067     {
2068         ast_expression *expr;
2069         if (parser->tok == '}')
2070             break;
2071
2072         if (!parse_statement(parser, block, &expr, false)) {
2073             /* parseerror(parser, "parse error"); */
2074             block = NULL;
2075             goto cleanup;
2076         }
2077         if (!expr)
2078             continue;
2079         vec_push(block->exprs, expr);
2080     }
2081
2082     if (parser->tok != '}') {
2083         block = NULL;
2084     } else {
2085         if (warnreturn && parser->function->vtype->expression.next->expression.vtype != TYPE_VOID)
2086         {
2087             if (!vec_size(block->exprs) ||
2088                 !ast_istype(vec_last(block->exprs), ast_return))
2089             {
2090                 if (parsewarning(parser, WARN_MISSING_RETURN_VALUES, "control reaches end of non-void function")) {
2091                     block = NULL;
2092                     goto cleanup;
2093                 }
2094             }
2095         }
2096         (void)parser_next(parser);
2097     }
2098
2099 cleanup:
2100     while (vec_size(parser->locals) > parser->blocklocal)
2101         retval = retval && parser_pop_local(parser);
2102     parser->blocklocal = oldblocklocal;
2103     return !!block;
2104 }
2105
2106 static ast_block* parse_block(parser_t *parser, bool warnreturn)
2107 {
2108     ast_block *block;
2109     block = ast_block_new(parser_ctx(parser));
2110     if (!block)
2111         return NULL;
2112     if (!parse_block_into(parser, block, warnreturn)) {
2113         ast_block_delete(block);
2114         return NULL;
2115     }
2116     return block;
2117 }
2118
2119 static ast_expression* parse_statement_or_block(parser_t *parser)
2120 {
2121     ast_expression *expr = NULL;
2122     if (parser->tok == '{')
2123         return (ast_expression*)parse_block(parser, false);
2124     if (!parse_statement(parser, NULL, &expr, false))
2125         return NULL;
2126     return expr;
2127 }
2128
2129 /* loop method */
2130 static bool create_vector_members(ast_value *var, varentry_t *ve)
2131 {
2132     size_t i;
2133     size_t len = strlen(var->name);
2134
2135     for (i = 0; i < 3; ++i) {
2136         ve[i].var = (ast_expression*)ast_member_new(ast_ctx(var), (ast_expression*)var, i);
2137         if (!ve[i].var)
2138             break;
2139
2140         ve[i].name = (char*)mem_a(len+3);
2141         if (!ve[i].name) {
2142             ast_delete(ve[i].var);
2143             break;
2144         }
2145
2146         memcpy(ve[i].name, var->name, len);
2147         ve[i].name[len]   = '_';
2148         ve[i].name[len+1] = 'x'+i;
2149         ve[i].name[len+2] = 0;
2150     }
2151     if (i == 3)
2152         return true;
2153
2154     /* unroll */
2155     do {
2156         --i;
2157         mem_d(ve[i].name);
2158         ast_delete(ve[i].var);
2159         ve[i].name = NULL;
2160         ve[i].var  = NULL;
2161     } while (i);
2162     return false;
2163 }
2164
2165 static bool parse_function_body(parser_t *parser, ast_value *var)
2166 {
2167     ast_block      *block = NULL;
2168     ast_function   *func;
2169     ast_function   *old;
2170     size_t          parami;
2171
2172     ast_expression *framenum  = NULL;
2173     ast_expression *nextthink = NULL;
2174     /* None of the following have to be deleted */
2175     ast_expression *fld_think = NULL, *fld_nextthink = NULL, *fld_frame = NULL;
2176     ast_expression *gbl_time = NULL, *gbl_self = NULL;
2177     bool            has_frame_think;
2178
2179     bool retval = true;
2180
2181     has_frame_think = false;
2182     old = parser->function;
2183
2184     if (var->expression.variadic) {
2185         if (parsewarning(parser, WARN_VARIADIC_FUNCTION,
2186                          "variadic function with implementation will not be able to access additional parameters"))
2187         {
2188             return false;
2189         }
2190     }
2191
2192     if (parser->tok == '[') {
2193         /* got a frame definition: [ framenum, nextthink ]
2194          * this translates to:
2195          * self.frame = framenum;
2196          * self.nextthink = time + 0.1;
2197          * self.think = nextthink;
2198          */
2199         nextthink = NULL;
2200
2201         fld_think     = parser_find_field(parser, "think");
2202         fld_nextthink = parser_find_field(parser, "nextthink");
2203         fld_frame     = parser_find_field(parser, "frame");
2204         if (!fld_think || !fld_nextthink || !fld_frame) {
2205             parseerror(parser, "cannot use [frame,think] notation without the required fields");
2206             parseerror(parser, "please declare the following entityfields: `frame`, `think`, `nextthink`");
2207             return false;
2208         }
2209         gbl_time      = parser_find_global(parser, "time");
2210         gbl_self      = parser_find_global(parser, "self");
2211         if (!gbl_time || !gbl_self) {
2212             parseerror(parser, "cannot use [frame,think] notation without the required globals");
2213             parseerror(parser, "please declare the following globals: `time`, `self`");
2214             return false;
2215         }
2216
2217         if (!parser_next(parser))
2218             return false;
2219
2220         framenum = parse_expression_leave(parser, true);
2221         if (!framenum) {
2222             parseerror(parser, "expected a framenumber constant in[frame,think] notation");
2223             return false;
2224         }
2225         if (!ast_istype(framenum, ast_value) || !( (ast_value*)framenum )->isconst) {
2226             ast_unref(framenum);
2227             parseerror(parser, "framenumber in [frame,think] notation must be a constant");
2228             return false;
2229         }
2230
2231         if (parser->tok != ',') {
2232             ast_unref(framenum);
2233             parseerror(parser, "expected comma after frame number in [frame,think] notation");
2234             parseerror(parser, "Got a %i\n", parser->tok);
2235             return false;
2236         }
2237
2238         if (!parser_next(parser)) {
2239             ast_unref(framenum);
2240             return false;
2241         }
2242
2243         if (parser->tok == TOKEN_IDENT && !parser_find_var(parser, parser_tokval(parser)))
2244         {
2245             /* qc allows the use of not-yet-declared functions here
2246              * - this automatically creates a prototype */
2247             varentry_t      varent;
2248             ast_value      *thinkfunc;
2249             ast_expression *functype = fld_think->expression.next;
2250
2251             thinkfunc = ast_value_new(parser_ctx(parser), parser_tokval(parser), functype->expression.vtype);
2252             if (!thinkfunc || !ast_type_adopt(thinkfunc, functype)) {
2253                 ast_unref(framenum);
2254                 parseerror(parser, "failed to create implicit prototype for `%s`", parser_tokval(parser));
2255                 return false;
2256             }
2257
2258             if (!parser_next(parser)) {
2259                 ast_unref(framenum);
2260                 ast_delete(thinkfunc);
2261                 return false;
2262             }
2263
2264             varent.var = (ast_expression*)thinkfunc;
2265             varent.name = util_strdup(thinkfunc->name);
2266             vec_push(parser->globals, varent);
2267             nextthink = (ast_expression*)thinkfunc;
2268
2269         } else {
2270             nextthink = parse_expression_leave(parser, true);
2271             if (!nextthink) {
2272                 ast_unref(framenum);
2273                 parseerror(parser, "expected a think-function in [frame,think] notation");
2274                 return false;
2275             }
2276         }
2277
2278         if (!ast_istype(nextthink, ast_value)) {
2279             parseerror(parser, "think-function in [frame,think] notation must be a constant");
2280             retval = false;
2281         }
2282
2283         if (retval && parser->tok != ']') {
2284             parseerror(parser, "expected closing `]` for [frame,think] notation");
2285             retval = false;
2286         }
2287
2288         if (retval && !parser_next(parser)) {
2289             retval = false;
2290         }
2291
2292         if (retval && parser->tok != '{') {
2293             parseerror(parser, "a function body has to be declared after a [frame,think] declaration");
2294             retval = false;
2295         }
2296
2297         if (!retval) {
2298             ast_unref(nextthink);
2299             ast_unref(framenum);
2300             return false;
2301         }
2302
2303         has_frame_think = true;
2304     }
2305
2306     block = ast_block_new(parser_ctx(parser));
2307     if (!block) {
2308         parseerror(parser, "failed to allocate block");
2309         if (has_frame_think) {
2310             ast_unref(nextthink);
2311             ast_unref(framenum);
2312         }
2313         return false;
2314     }
2315
2316     if (has_frame_think) {
2317         lex_ctx ctx;
2318         ast_expression *self_frame;
2319         ast_expression *self_nextthink;
2320         ast_expression *self_think;
2321         ast_expression *time_plus_1;
2322         ast_store *store_frame;
2323         ast_store *store_nextthink;
2324         ast_store *store_think;
2325
2326         ctx = parser_ctx(parser);
2327         self_frame     = (ast_expression*)ast_entfield_new(ctx, gbl_self, fld_frame);
2328         self_nextthink = (ast_expression*)ast_entfield_new(ctx, gbl_self, fld_nextthink);
2329         self_think     = (ast_expression*)ast_entfield_new(ctx, gbl_self, fld_think);
2330
2331         time_plus_1    = (ast_expression*)ast_binary_new(ctx, INSTR_ADD_F,
2332                          gbl_time, (ast_expression*)parser_const_float(parser, 0.1));
2333
2334         if (!self_frame || !self_nextthink || !self_think || !time_plus_1) {
2335             if (self_frame)     ast_delete(self_frame);
2336             if (self_nextthink) ast_delete(self_nextthink);
2337             if (self_think)     ast_delete(self_think);
2338             if (time_plus_1)    ast_delete(time_plus_1);
2339             retval = false;
2340         }
2341
2342         if (retval)
2343         {
2344             store_frame     = ast_store_new(ctx, INSTR_STOREP_F,   self_frame,     framenum);
2345             store_nextthink = ast_store_new(ctx, INSTR_STOREP_F,   self_nextthink, time_plus_1);
2346             store_think     = ast_store_new(ctx, INSTR_STOREP_FNC, self_think,     nextthink);
2347
2348             if (!store_frame) {
2349                 ast_delete(self_frame);
2350                 retval = false;
2351             }
2352             if (!store_nextthink) {
2353                 ast_delete(self_nextthink);
2354                 retval = false;
2355             }
2356             if (!store_think) {
2357                 ast_delete(self_think);
2358                 retval = false;
2359             }
2360             if (!retval) {
2361                 if (store_frame)     ast_delete(store_frame);
2362                 if (store_nextthink) ast_delete(store_nextthink);
2363                 if (store_think)     ast_delete(store_think);
2364                 retval = false;
2365             }
2366             vec_push(block->exprs, (ast_expression*)store_frame);
2367             vec_push(block->exprs, (ast_expression*)store_nextthink);
2368             vec_push(block->exprs, (ast_expression*)store_think);
2369         }
2370
2371         if (!retval) {
2372             parseerror(parser, "failed to generate code for [frame,think]");
2373             ast_unref(nextthink);
2374             ast_unref(framenum);
2375             ast_delete(block);
2376             return false;
2377         }
2378     }
2379
2380     for (parami = 0; parami < vec_size(var->expression.params); ++parami) {
2381         size_t     e;
2382         varentry_t ve[3];
2383         ast_value *param = var->expression.params[parami];
2384
2385         if (param->expression.vtype != TYPE_VECTOR &&
2386             (param->expression.vtype != TYPE_FIELD ||
2387              param->expression.next->expression.vtype != TYPE_VECTOR))
2388         {
2389             continue;
2390         }
2391
2392         if (!create_vector_members(param, ve)) {
2393             ast_block_delete(block);
2394             return false;
2395         }
2396
2397         for (e = 0; e < 3; ++e) {
2398             vec_push(parser->locals, ve[e]);
2399             ast_block_collect(block, ve[e].var);
2400             ve[e].var = NULL; /* collected */
2401         }
2402     }
2403
2404     func = ast_function_new(ast_ctx(var), var->name, var);
2405     if (!func) {
2406         parseerror(parser, "failed to allocate function for `%s`", var->name);
2407         ast_block_delete(block);
2408         goto enderr;
2409     }
2410     vec_push(parser->functions, func);
2411
2412     parser->function = func;
2413     if (!parse_block_into(parser, block, true)) {
2414         ast_block_delete(block);
2415         goto enderrfn;
2416     }
2417
2418     vec_push(func->blocks, block);
2419
2420     parser->function = old;
2421     while (vec_size(parser->locals))
2422         retval = retval && parser_pop_local(parser);
2423
2424     if (parser->tok == ';')
2425         return parser_next(parser);
2426     else if (opts_standard == COMPILER_QCC)
2427         parseerror(parser, "missing semicolon after function body (mandatory with -std=qcc)");
2428     return retval;
2429
2430 enderrfn:
2431     vec_pop(parser->functions);
2432     ast_function_delete(func);
2433     var->constval.vfunc = NULL;
2434
2435 enderr:
2436     while (vec_size(parser->locals)) {
2437         mem_d(vec_last(parser->locals).name);
2438         vec_pop(parser->locals);
2439     }
2440     parser->function = old;
2441     return false;
2442 }
2443
2444 static ast_expression *array_accessor_split(
2445     parser_t  *parser,
2446     ast_value *array,
2447     ast_value *index,
2448     size_t     middle,
2449     ast_expression *left,
2450     ast_expression *right
2451     )
2452 {
2453     ast_ifthen *ifthen;
2454     ast_binary *cmp;
2455
2456     lex_ctx ctx = ast_ctx(array);
2457
2458     if (!left || !right) {
2459         if (left)  ast_delete(left);
2460         if (right) ast_delete(right);
2461         return NULL;
2462     }
2463
2464     cmp = ast_binary_new(ctx, INSTR_LT,
2465                          (ast_expression*)index,
2466                          (ast_expression*)parser_const_float(parser, middle));
2467     if (!cmp) {
2468         ast_delete(left);
2469         ast_delete(right);
2470         parseerror(parser, "internal error: failed to create comparison for array setter");
2471         return NULL;
2472     }
2473
2474     ifthen = ast_ifthen_new(ctx, (ast_expression*)cmp, left, right);
2475     if (!ifthen) {
2476         ast_delete(cmp); /* will delete left and right */
2477         parseerror(parser, "internal error: failed to create conditional jump for array setter");
2478         return NULL;
2479     }
2480
2481     return (ast_expression*)ifthen;
2482 }
2483
2484 static ast_expression *array_setter_node(parser_t *parser, ast_value *array, ast_value *index, ast_value *value, size_t from, size_t afterend)
2485 {
2486     lex_ctx ctx = ast_ctx(array);
2487
2488     if (from+1 == afterend) {
2489         /* set this value */
2490         ast_block       *block;
2491         ast_return      *ret;
2492         ast_array_index *subscript;
2493         ast_store       *st;
2494         int assignop = type_store_instr[value->expression.vtype];
2495
2496         if (value->expression.vtype == TYPE_FIELD && value->expression.next->expression.vtype == TYPE_VECTOR)
2497             assignop = INSTR_STORE_V;
2498
2499         subscript = ast_array_index_new(ctx, (ast_expression*)array, (ast_expression*)parser_const_float(parser, from));
2500         if (!subscript)
2501             return NULL;
2502
2503         st = ast_store_new(ctx, assignop, (ast_expression*)subscript, (ast_expression*)value);
2504         if (!st) {
2505             ast_delete(subscript);
2506             return NULL;
2507         }
2508
2509         block = ast_block_new(ctx);
2510         if (!block) {
2511             ast_delete(st);
2512             return NULL;
2513         }
2514
2515         vec_push(block->exprs, (ast_expression*)st);
2516
2517         ret = ast_return_new(ctx, NULL);
2518         if (!ret) {
2519             ast_delete(block);
2520             return NULL;
2521         }
2522
2523         vec_push(block->exprs, (ast_expression*)ret);
2524
2525         return (ast_expression*)block;
2526     } else {
2527         ast_expression *left, *right;
2528         size_t diff = afterend - from;
2529         size_t middle = from + diff/2;
2530         left  = array_setter_node(parser, array, index, value, from, middle);
2531         right = array_setter_node(parser, array, index, value, middle, afterend);
2532         return array_accessor_split(parser, array, index, middle, left, right);
2533     }
2534 }
2535
2536 static ast_expression *array_field_setter_node(
2537     parser_t  *parser,
2538     ast_value *array,
2539     ast_value *entity,
2540     ast_value *index,
2541     ast_value *value,
2542     size_t     from,
2543     size_t     afterend)
2544 {
2545     lex_ctx ctx = ast_ctx(array);
2546
2547     if (from+1 == afterend) {
2548         /* set this value */
2549         ast_block       *block;
2550         ast_return      *ret;
2551         ast_entfield    *entfield;
2552         ast_array_index *subscript;
2553         ast_store       *st;
2554         int assignop = type_storep_instr[value->expression.vtype];
2555
2556         if (value->expression.vtype == TYPE_FIELD && value->expression.next->expression.vtype == TYPE_VECTOR)
2557             assignop = INSTR_STOREP_V;
2558
2559         subscript = ast_array_index_new(ctx, (ast_expression*)array, (ast_expression*)parser_const_float(parser, from));
2560         if (!subscript)
2561             return NULL;
2562
2563         entfield = ast_entfield_new_force(ctx,
2564                                           (ast_expression*)entity,
2565                                           (ast_expression*)subscript,
2566                                           (ast_expression*)subscript);
2567         if (!entfield) {
2568             ast_delete(subscript);
2569             return NULL;
2570         }
2571
2572         st = ast_store_new(ctx, assignop, (ast_expression*)entfield, (ast_expression*)value);
2573         if (!st) {
2574             ast_delete(entfield);
2575             return NULL;
2576         }
2577
2578         block = ast_block_new(ctx);
2579         if (!block) {
2580             ast_delete(st);
2581             return NULL;
2582         }
2583
2584         vec_push(block->exprs, (ast_expression*)st);
2585
2586         ret = ast_return_new(ctx, NULL);
2587         if (!ret) {
2588             ast_delete(block);
2589             return NULL;
2590         }
2591
2592         vec_push(block->exprs, (ast_expression*)ret);
2593
2594         return (ast_expression*)block;
2595     } else {
2596         ast_expression *left, *right;
2597         size_t diff = afterend - from;
2598         size_t middle = from + diff/2;
2599         left  = array_field_setter_node(parser, array, entity, index, value, from, middle);
2600         right = array_field_setter_node(parser, array, entity, index, value, middle, afterend);
2601         return array_accessor_split(parser, array, index, middle, left, right);
2602     }
2603 }
2604
2605 static ast_expression *array_getter_node(parser_t *parser, ast_value *array, ast_value *index, size_t from, size_t afterend)
2606 {
2607     lex_ctx ctx = ast_ctx(array);
2608
2609     if (from+1 == afterend) {
2610         ast_return      *ret;
2611         ast_array_index *subscript;
2612
2613         subscript = ast_array_index_new(ctx, (ast_expression*)array, (ast_expression*)parser_const_float(parser, from));
2614         if (!subscript)
2615             return NULL;
2616
2617         ret = ast_return_new(ctx, (ast_expression*)subscript);
2618         if (!ret) {
2619             ast_delete(subscript);
2620             return NULL;
2621         }
2622
2623         return (ast_expression*)ret;
2624     } else {
2625         ast_expression *left, *right;
2626         size_t diff = afterend - from;
2627         size_t middle = from + diff/2;
2628         left  = array_getter_node(parser, array, index, from, middle);
2629         right = array_getter_node(parser, array, index, middle, afterend);
2630         return array_accessor_split(parser, array, index, middle, left, right);
2631     }
2632 }
2633
2634 static bool parser_create_array_accessor(parser_t *parser, ast_value *array, const char *funcname, ast_value **out)
2635 {
2636     ast_function   *func = NULL;
2637     ast_value      *fval = NULL;
2638     ast_block      *body = NULL;
2639
2640     fval = ast_value_new(ast_ctx(array), funcname, TYPE_FUNCTION);
2641     if (!fval) {
2642         parseerror(parser, "failed to create accessor function value");
2643         return false;
2644     }
2645
2646     func = ast_function_new(ast_ctx(array), funcname, fval);
2647     if (!func) {
2648         ast_delete(fval);
2649         parseerror(parser, "failed to create accessor function node");
2650         return false;
2651     }
2652
2653     body = ast_block_new(ast_ctx(array));
2654     if (!body) {
2655         parseerror(parser, "failed to create block for array accessor");
2656         ast_delete(fval);
2657         ast_delete(func);
2658         return false;
2659     }
2660
2661     vec_push(func->blocks, body);
2662     *out = fval;
2663
2664     vec_push(parser->accessors, fval);
2665
2666     return true;
2667 }
2668
2669 static bool parser_create_array_setter(parser_t *parser, ast_value *array, const char *funcname)
2670 {
2671     ast_expression *root = NULL;
2672     ast_value      *index = NULL;
2673     ast_value      *value = NULL;
2674     ast_function   *func;
2675     ast_value      *fval;
2676
2677     if (!ast_istype(array->expression.next, ast_value)) {
2678         parseerror(parser, "internal error: array accessor needs to build an ast_value with a copy of the element type");
2679         return false;
2680     }
2681
2682     if (!parser_create_array_accessor(parser, array, funcname, &fval))
2683         return false;
2684     func = fval->constval.vfunc;
2685     fval->expression.next = (ast_expression*)ast_value_new(ast_ctx(array), "<void>", TYPE_VOID);
2686
2687     index = ast_value_new(ast_ctx(array), "index", TYPE_FLOAT);
2688     value = ast_value_copy((ast_value*)array->expression.next);
2689
2690     if (!index || !value) {
2691         parseerror(parser, "failed to create locals for array accessor");
2692         goto cleanup;
2693     }
2694     (void)!ast_value_set_name(value, "value"); /* not important */
2695     vec_push(fval->expression.params, index);
2696     vec_push(fval->expression.params, value);
2697
2698     root = array_setter_node(parser, array, index, value, 0, array->expression.count);
2699     if (!root) {
2700         parseerror(parser, "failed to build accessor search tree");
2701         goto cleanup;
2702     }
2703
2704     vec_push(func->blocks[0]->exprs, root);
2705     array->setter = fval;
2706     return true;
2707 cleanup:
2708     if (index) ast_delete(index);
2709     if (value) ast_delete(value);
2710     if (root)  ast_delete(root);
2711     ast_delete(func);
2712     ast_delete(fval);
2713     return false;
2714 }
2715
2716 static bool parser_create_array_field_setter(parser_t *parser, ast_value *array, const char *funcname)
2717 {
2718     ast_expression *root = NULL;
2719     ast_value      *entity = NULL;
2720     ast_value      *index = NULL;
2721     ast_value      *value = NULL;
2722     ast_function   *func;
2723     ast_value      *fval;
2724
2725     if (!ast_istype(array->expression.next, ast_value)) {
2726         parseerror(parser, "internal error: array accessor needs to build an ast_value with a copy of the element type");
2727         return false;
2728     }
2729
2730     if (!parser_create_array_accessor(parser, array, funcname, &fval))
2731         return false;
2732     func = fval->constval.vfunc;
2733     fval->expression.next = (ast_expression*)ast_value_new(ast_ctx(array), "<void>", TYPE_VOID);
2734
2735     entity = ast_value_new(ast_ctx(array), "entity", TYPE_ENTITY);
2736     index  = ast_value_new(ast_ctx(array), "index",  TYPE_FLOAT);
2737     value  = ast_value_copy((ast_value*)array->expression.next);
2738     if (!entity || !index || !value) {
2739         parseerror(parser, "failed to create locals for array accessor");
2740         goto cleanup;
2741     }
2742     (void)!ast_value_set_name(value, "value"); /* not important */
2743     vec_push(fval->expression.params, entity);
2744     vec_push(fval->expression.params, index);
2745     vec_push(fval->expression.params, value);
2746
2747     root = array_field_setter_node(parser, array, entity, index, value, 0, array->expression.count);
2748     if (!root) {
2749         parseerror(parser, "failed to build accessor search tree");
2750         goto cleanup;
2751     }
2752
2753     vec_push(func->blocks[0]->exprs, root);
2754     array->setter = fval;
2755     return true;
2756 cleanup:
2757     if (entity) ast_delete(entity);
2758     if (index)  ast_delete(index);
2759     if (value)  ast_delete(value);
2760     if (root)   ast_delete(root);
2761     ast_delete(func);
2762     ast_delete(fval);
2763     return false;
2764 }
2765
2766 static bool parser_create_array_getter(parser_t *parser, ast_value *array, const ast_expression *elemtype, const char *funcname)
2767 {
2768     ast_expression *root = NULL;
2769     ast_value      *index = NULL;
2770     ast_value      *fval;
2771     ast_function   *func;
2772
2773     /* NOTE: checking array->expression.next rather than elemtype since
2774      * for fields elemtype is a temporary fieldtype.
2775      */
2776     if (!ast_istype(array->expression.next, ast_value)) {
2777         parseerror(parser, "internal error: array accessor needs to build an ast_value with a copy of the element type");
2778         return false;
2779     }
2780
2781     if (!parser_create_array_accessor(parser, array, funcname, &fval))
2782         return false;
2783     func = fval->constval.vfunc;
2784     fval->expression.next = ast_type_copy(ast_ctx(array), elemtype);
2785
2786     index = ast_value_new(ast_ctx(array), "index", TYPE_FLOAT);
2787
2788     if (!index) {
2789         parseerror(parser, "failed to create locals for array accessor");
2790         goto cleanup;
2791     }
2792     vec_push(fval->expression.params, index);
2793
2794     root = array_getter_node(parser, array, index, 0, array->expression.count);
2795     if (!root) {
2796         parseerror(parser, "failed to build accessor search tree");
2797         goto cleanup;
2798     }
2799
2800     vec_push(func->blocks[0]->exprs, root);
2801     array->getter = fval;
2802     return true;
2803 cleanup:
2804     if (index) ast_delete(index);
2805     if (root)  ast_delete(root);
2806     ast_delete(func);
2807     ast_delete(fval);
2808     return false;
2809 }
2810
2811 static ast_value *parse_typename(parser_t *parser, ast_value **storebase);
2812 static ast_value *parse_parameter_list(parser_t *parser, ast_value *var)
2813 {
2814     lex_ctx     ctx;
2815     size_t      i;
2816     ast_value **params;
2817     ast_value  *param;
2818     ast_value  *fval;
2819     bool        first = true;
2820     bool        variadic = false;
2821
2822     ctx = parser_ctx(parser);
2823
2824     /* for the sake of less code we parse-in in this function */
2825     if (!parser_next(parser)) {
2826         parseerror(parser, "expected parameter list");
2827         return NULL;
2828     }
2829
2830     params = NULL;
2831
2832     /* parse variables until we hit a closing paren */
2833     while (parser->tok != ')') {
2834         if (!first) {
2835             /* there must be commas between them */
2836             if (parser->tok != ',') {
2837                 parseerror(parser, "expected comma or end of parameter list");
2838                 goto on_error;
2839             }
2840             if (!parser_next(parser)) {
2841                 parseerror(parser, "expected parameter");
2842                 goto on_error;
2843             }
2844         }
2845         first = false;
2846
2847         if (parser->tok == TOKEN_DOTS) {
2848             /* '...' indicates a varargs function */
2849             variadic = true;
2850             if (!parser_next(parser)) {
2851                 parseerror(parser, "expected parameter");
2852                 return NULL;
2853             }
2854             if (parser->tok != ')') {
2855                 parseerror(parser, "`...` must be the last parameter of a variadic function declaration");
2856                 goto on_error;
2857             }
2858         }
2859         else
2860         {
2861             /* for anything else just parse a typename */
2862             param = parse_typename(parser, NULL);
2863             if (!param)
2864                 goto on_error;
2865             vec_push(params, param);
2866             if (param->expression.vtype >= TYPE_VARIANT) {
2867                 char typename[1024];
2868                 ast_type_to_string((ast_expression*)param, typename, sizeof(typename));
2869                 parseerror(parser, "type not supported as part of a parameter list: %s", typename);
2870                 goto on_error;
2871             }
2872         }
2873     }
2874
2875     /* sanity check */
2876     if (vec_size(params) > 8 && opts_standard == COMPILER_QCC)
2877         (void)!parsewarning(parser, WARN_EXTENSIONS, "more than 8 parameters are not supported by this standard");
2878
2879     /* parse-out */
2880     if (!parser_next(parser)) {
2881         parseerror(parser, "parse error after typename");
2882         goto on_error;
2883     }
2884
2885     /* now turn 'var' into a function type */
2886     fval = ast_value_new(ctx, "<type()>", TYPE_FUNCTION);
2887     fval->expression.next     = (ast_expression*)var;
2888     fval->expression.variadic = variadic;
2889     var = fval;
2890
2891     var->expression.params = params;
2892     params = NULL;
2893
2894     return var;
2895
2896 on_error:
2897     ast_delete(var);
2898     for (i = 0; i < vec_size(params); ++i)
2899         ast_delete(params[i]);
2900     vec_free(params);
2901     return NULL;
2902 }
2903
2904 static ast_value *parse_arraysize(parser_t *parser, ast_value *var)
2905 {
2906     ast_expression *cexp;
2907     ast_value      *cval, *tmp;
2908     lex_ctx ctx;
2909
2910     ctx = parser_ctx(parser);
2911
2912     if (!parser_next(parser)) {
2913         ast_delete(var);
2914         parseerror(parser, "expected array-size");
2915         return NULL;
2916     }
2917
2918     cexp = parse_expression_leave(parser, true);
2919
2920     if (!cexp || !ast_istype(cexp, ast_value)) {
2921         if (cexp)
2922             ast_unref(cexp);
2923         ast_delete(var);
2924         parseerror(parser, "expected array-size as constant positive integer");
2925         return NULL;
2926     }
2927     cval = (ast_value*)cexp;
2928
2929     tmp = ast_value_new(ctx, "<type[]>", TYPE_ARRAY);
2930     tmp->expression.next = (ast_expression*)var;
2931     var = tmp;
2932
2933     if (cval->expression.vtype == TYPE_INTEGER)
2934         tmp->expression.count = cval->constval.vint;
2935     else if (cval->expression.vtype == TYPE_FLOAT)
2936         tmp->expression.count = cval->constval.vfloat;
2937     else {
2938         ast_unref(cexp);
2939         ast_delete(var);
2940         parseerror(parser, "array-size must be a positive integer constant");
2941         return NULL;
2942     }
2943     ast_unref(cexp);
2944
2945     if (parser->tok != ']') {
2946         ast_delete(var);
2947         parseerror(parser, "expected ']' after array-size");
2948         return NULL;
2949     }
2950     if (!parser_next(parser)) {
2951         ast_delete(var);
2952         parseerror(parser, "error after parsing array size");
2953         return NULL;
2954     }
2955     return var;
2956 }
2957
2958 /* Parse a complete typename.
2959  * for single-variables (ie. function parameters or typedefs) storebase should be NULL
2960  * but when parsing variables separated by comma
2961  * 'storebase' should point to where the base-type should be kept.
2962  * The base type makes up every bit of type information which comes *before* the
2963  * variable name.
2964  *
2965  * The following will be parsed in its entirety:
2966  *     void() foo()
2967  * The 'basetype' in this case is 'void()'
2968  * and if there's a comma after it, say:
2969  *     void() foo(), bar
2970  * then the type-information 'void()' can be stored in 'storebase'
2971  */
2972 static ast_value *parse_typename(parser_t *parser, ast_value **storebase)
2973 {
2974     ast_value *var, *tmp;
2975     lex_ctx    ctx;
2976
2977     const char *name = NULL;
2978     bool        isfield  = false;
2979     bool        wasarray = false;
2980
2981     ctx = parser_ctx(parser);
2982
2983     /* types may start with a dot */
2984     if (parser->tok == '.') {
2985         isfield = true;
2986         /* if we parsed a dot we need a typename now */
2987         if (!parser_next(parser)) {
2988             parseerror(parser, "expected typename for field definition");
2989             return NULL;
2990         }
2991         if (parser->tok != TOKEN_TYPENAME) {
2992             parseerror(parser, "expected typename");
2993             return NULL;
2994         }
2995     }
2996
2997     /* generate the basic type value */
2998     var = ast_value_new(ctx, "<type>", parser_token(parser)->constval.t);
2999     /* do not yet turn into a field - remember:
3000      * .void() foo; is a field too
3001      * .void()() foo; is a function
3002      */
3003
3004     /* parse on */
3005     if (!parser_next(parser)) {
3006         ast_delete(var);
3007         parseerror(parser, "parse error after typename");
3008         return NULL;
3009     }
3010
3011     /* an opening paren now starts the parameter-list of a function
3012      * this is where original-QC has parameter lists.
3013      * We allow a single parameter list here.
3014      * Much like fteqcc we don't allow `float()() x`
3015      */
3016     if (parser->tok == '(') {
3017         var = parse_parameter_list(parser, var);
3018         if (!var)
3019             return NULL;
3020     }
3021
3022     /* store the base if requested */
3023     if (storebase) {
3024         *storebase = ast_value_copy(var);
3025         if (isfield) {
3026             tmp = ast_value_new(ctx, "<type:f>", TYPE_FIELD);
3027             tmp->expression.next = (ast_expression*)*storebase;
3028             *storebase = tmp;
3029         }
3030     }
3031
3032     /* there may be a name now */
3033     if (parser->tok == TOKEN_IDENT) {
3034         name = util_strdup(parser_tokval(parser));
3035         /* parse on */
3036         if (!parser_next(parser)) {
3037             ast_delete(var);
3038             parseerror(parser, "error after variable or field declaration");
3039             return NULL;
3040         }
3041     }
3042
3043     /* now this may be an array */
3044     if (parser->tok == '[') {
3045         wasarray = true;
3046         var = parse_arraysize(parser, var);
3047         if (!var)
3048             return NULL;
3049     }
3050
3051     /* This is the point where we can turn it into a field */
3052     if (isfield) {
3053         /* turn it into a field if desired */
3054         tmp = ast_value_new(ctx, "<type:f>", TYPE_FIELD);
3055         tmp->expression.next = (ast_expression*)var;
3056         var = tmp;
3057     }
3058
3059     /* now there may be function parens again */
3060     if (parser->tok == '(' && opts_standard == COMPILER_QCC)
3061         parseerror(parser, "C-style function syntax is not allowed in -std=qcc");
3062     if (parser->tok == '(' && wasarray)
3063         parseerror(parser, "arrays as part of a return type is not supported");
3064     while (parser->tok == '(') {
3065         var = parse_parameter_list(parser, var);
3066         if (!var) {
3067             if (name)
3068                 mem_d((void*)name);
3069             ast_delete(var);
3070             return NULL;
3071         }
3072     }
3073
3074     /* finally name it */
3075     if (name) {
3076         if (!ast_value_set_name(var, name)) {
3077             ast_delete(var);
3078             parseerror(parser, "internal error: failed to set name");
3079             return NULL;
3080         }
3081         /* free the name, ast_value_set_name duplicates */
3082         mem_d((void*)name);
3083     }
3084
3085     return var;
3086 }
3087
3088 static bool parse_variable(parser_t *parser, ast_block *localblock, bool nofields)
3089 {
3090     ast_value *var;
3091     ast_value *proto;
3092     ast_expression *old;
3093     bool       was_end;
3094     size_t     i;
3095
3096     ast_value *basetype = NULL;
3097     bool      retval    = true;
3098     bool      isparam   = false;
3099     bool      isvector  = false;
3100     bool      cleanvar  = true;
3101     bool      wasarray  = false;
3102
3103     varentry_t varent, ve[3];
3104
3105     /* get the first complete variable */
3106     var = parse_typename(parser, &basetype);
3107     if (!var) {
3108         if (basetype)
3109             ast_delete(basetype);
3110         return false;
3111     }
3112
3113     memset(&varent, 0, sizeof(varent));
3114     memset(&ve, 0, sizeof(ve));
3115
3116     while (true) {
3117         proto = NULL;
3118         wasarray = false;
3119
3120         /* Part 0: finish the type */
3121         if (parser->tok == '(') {
3122             if (opts_standard == COMPILER_QCC)
3123                 parseerror(parser, "C-style function syntax is not allowed in -std=qcc");
3124             var = parse_parameter_list(parser, var);
3125             if (!var) {
3126                 retval = false;
3127                 goto cleanup;
3128             }
3129         }
3130         /* we only allow 1-dimensional arrays */
3131         if (parser->tok == '[') {
3132             wasarray = true;
3133             var = parse_arraysize(parser, var);
3134             if (!var) {
3135                 retval = false;
3136                 goto cleanup;
3137             }
3138         }
3139         if (parser->tok == '(' && wasarray) {
3140             parseerror(parser, "arrays as part of a return type is not supported");
3141             /* we'll still parse the type completely for now */
3142         }
3143         /* for functions returning functions */
3144         while (parser->tok == '(') {
3145             if (opts_standard == COMPILER_QCC)
3146                 parseerror(parser, "C-style function syntax is not allowed in -std=qcc");
3147             var = parse_parameter_list(parser, var);
3148             if (!var) {
3149                 retval = false;
3150                 goto cleanup;
3151             }
3152         }
3153
3154         /* Part 1:
3155          * check for validity: (end_sys_..., multiple-definitions, prototypes, ...)
3156          * Also: if there was a prototype, `var` will be deleted and set to `proto` which
3157          * is then filled with the previous definition and the parameter-names replaced.
3158          */
3159         if (!localblock) {
3160             /* Deal with end_sys_ vars */
3161             was_end = false;
3162             if (!strcmp(var->name, "end_sys_globals")) {
3163                 parser->crc_globals = vec_size(parser->globals);
3164                 was_end = true;
3165             }
3166             else if (!strcmp(var->name, "end_sys_fields")) {
3167                 parser->crc_fields = vec_size(parser->fields);
3168                 was_end = true;
3169             }
3170             if (was_end && var->expression.vtype == TYPE_FIELD) {
3171                 if (parsewarning(parser, WARN_END_SYS_FIELDS,
3172                                  "global '%s' hint should not be a field",
3173                                  parser_tokval(parser)))
3174                 {
3175                     retval = false;
3176                     goto cleanup;
3177                 }
3178             }
3179
3180             if (!nofields && var->expression.vtype == TYPE_FIELD)
3181             {
3182                 /* deal with field declarations */
3183                 old = parser_find_field(parser, var->name);
3184                 if (old) {
3185                     if (parsewarning(parser, WARN_FIELD_REDECLARED, "field `%s` already declared here: %s:%i",
3186                                      var->name, ast_ctx(old).file, (int)ast_ctx(old).line))
3187                     {
3188                         retval = false;
3189                         goto cleanup;
3190                     }
3191                     ast_delete(var);
3192                     var = NULL;
3193                     goto skipvar;
3194                     /*
3195                     parseerror(parser, "field `%s` already declared here: %s:%i",
3196                                var->name, ast_ctx(old).file, ast_ctx(old).line);
3197                     retval = false;
3198                     goto cleanup;
3199                     */
3200                 }
3201                 if (opts_standard == COMPILER_QCC &&
3202                     (old = parser_find_global(parser, var->name)))
3203                 {
3204                     parseerror(parser, "cannot declare a field and a global of the same name with -std=qcc");
3205                     parseerror(parser, "field `%s` already declared here: %s:%i",
3206                                var->name, ast_ctx(old).file, ast_ctx(old).line);
3207                     retval = false;
3208                     goto cleanup;
3209                 }
3210             }
3211             else
3212             {
3213                 /* deal with other globals */
3214                 old = parser_find_global(parser, var->name);
3215                 if (old && var->expression.vtype == TYPE_FUNCTION && old->expression.vtype == TYPE_FUNCTION)
3216                 {
3217                     /* This is a function which had a prototype */
3218                     if (!ast_istype(old, ast_value)) {
3219                         parseerror(parser, "internal error: prototype is not an ast_value");
3220                         retval = false;
3221                         goto cleanup;
3222                     }
3223                     proto = (ast_value*)old;
3224                     if (!ast_compare_type((ast_expression*)proto, (ast_expression*)var)) {
3225                         parseerror(parser, "conflicting types for `%s`, previous declaration was here: %s:%i",
3226                                    proto->name,
3227                                    ast_ctx(proto).file, ast_ctx(proto).line);
3228                         retval = false;
3229                         goto cleanup;
3230                     }
3231                     /* we need the new parameter-names */
3232                     for (i = 0; i < vec_size(proto->expression.params); ++i)
3233                         ast_value_set_name(proto->expression.params[i], var->expression.params[i]->name);
3234                     ast_delete(var);
3235                     var = proto;
3236                 }
3237                 else
3238                 {
3239                     /* other globals */
3240                     if (old) {
3241                         parseerror(parser, "global `%s` already declared here: %s:%i",
3242                                    var->name, ast_ctx(old).file, ast_ctx(old).line);
3243                         retval = false;
3244                         goto cleanup;
3245                     }
3246                     if (opts_standard == COMPILER_QCC &&
3247                         (old = parser_find_field(parser, var->name)))
3248                     {
3249                         parseerror(parser, "cannot declare a field and a global of the same name with -std=qcc");
3250                         parseerror(parser, "global `%s` already declared here: %s:%i",
3251                                    var->name, ast_ctx(old).file, ast_ctx(old).line);
3252                         retval = false;
3253                         goto cleanup;
3254                     }
3255                 }
3256             }
3257         }
3258         else /* it's not a global */
3259         {
3260             old = parser_find_local(parser, var->name, parser->blocklocal, &isparam);
3261             if (old && !isparam) {
3262                 parseerror(parser, "local `%s` already declared here: %s:%i",
3263                            var->name, ast_ctx(old).file, (int)ast_ctx(old).line);
3264                 retval = false;
3265                 goto cleanup;
3266             }
3267             old = parser_find_local(parser, var->name, 0, &isparam);
3268             if (old && isparam) {
3269                 if (parsewarning(parser, WARN_LOCAL_SHADOWS,
3270                                  "local `%s` is shadowing a parameter", var->name))
3271                 {
3272                     parseerror(parser, "local `%s` already declared here: %s:%i",
3273                                var->name, ast_ctx(old).file, (int)ast_ctx(old).line);
3274                     retval = false;
3275                     goto cleanup;
3276                 }
3277                 if (opts_standard != COMPILER_GMQCC) {
3278                     ast_delete(var);
3279                     var = NULL;
3280                     goto skipvar;
3281                 }
3282             }
3283         }
3284
3285         /* Part 2:
3286          * Create the global/local, and deal with vector types.
3287          */
3288         if (!proto) {
3289             if (var->expression.vtype == TYPE_VECTOR)
3290                 isvector = true;
3291             else if (var->expression.vtype == TYPE_FIELD &&
3292                      var->expression.next->expression.vtype == TYPE_VECTOR)
3293                 isvector = true;
3294
3295             if (isvector) {
3296                 if (!create_vector_members(var, ve)) {
3297                     retval = false;
3298                     goto cleanup;
3299                 }
3300             }
3301
3302             varent.name = util_strdup(var->name);
3303             varent.var  = (ast_expression*)var;
3304
3305             if (!localblock) {
3306                 /* deal with global variables, fields, functions */
3307                 if (!nofields && var->expression.vtype == TYPE_FIELD) {
3308                     vec_push(parser->fields, varent);
3309                     if (isvector) {
3310                         for (i = 0; i < 3; ++i)
3311                             vec_push(parser->fields, ve[i]);
3312                     }
3313                 }
3314                 else {
3315                     vec_push(parser->globals, varent);
3316                     if (isvector) {
3317                         for (i = 0; i < 3; ++i)
3318                             vec_push(parser->globals, ve[i]);
3319                     }
3320                 }
3321             } else {
3322                 vec_push(parser->locals, varent);
3323                 vec_push(localblock->locals, var);
3324                 if (isvector) {
3325                     for (i = 0; i < 3; ++i) {
3326                         vec_push(parser->locals, ve[i]);
3327                         ast_block_collect(localblock, ve[i].var);
3328                         ve[i].var = NULL; /* from here it's being collected in the block */
3329                     }
3330                 }
3331             }
3332
3333             varent.name = NULL;
3334             ve[0].name = ve[1].name = ve[2].name = NULL;
3335             ve[0].var  = ve[1].var  = ve[2].var  = NULL;
3336             cleanvar = false;
3337         }
3338         /* Part 2.2
3339          * deal with arrays
3340          */
3341         if (var->expression.vtype == TYPE_ARRAY) {
3342             char name[1024];
3343             snprintf(name, sizeof(name), "%s##SET", var->name);
3344             if (!parser_create_array_setter(parser, var, name))
3345                 goto cleanup;
3346             snprintf(name, sizeof(name), "%s##GET", var->name);
3347             if (!parser_create_array_getter(parser, var, var->expression.next, name))
3348                 goto cleanup;
3349         }
3350         else if (!localblock && !nofields &&
3351                  var->expression.vtype == TYPE_FIELD &&
3352                  var->expression.next->expression.vtype == TYPE_ARRAY)
3353         {
3354             char name[1024];
3355             ast_expression *telem;
3356             ast_value      *tfield;
3357             ast_value      *array = (ast_value*)var->expression.next;
3358
3359             if (!ast_istype(var->expression.next, ast_value)) {
3360                 parseerror(parser, "internal error: field element type must be an ast_value");
3361                 goto cleanup;
3362             }
3363
3364             snprintf(name, sizeof(name), "%s##SETF", var->name);
3365             if (!parser_create_array_field_setter(parser, array, name))
3366                 goto cleanup;
3367
3368             telem = ast_type_copy(ast_ctx(var), array->expression.next);
3369             tfield = ast_value_new(ast_ctx(var), "<.type>", TYPE_FIELD);
3370             tfield->expression.next = telem;
3371             snprintf(name, sizeof(name), "%s##GETFP", var->name);
3372             if (!parser_create_array_getter(parser, array, (ast_expression*)tfield, name)) {
3373                 ast_delete(tfield);
3374                 goto cleanup;
3375             }
3376             ast_delete(tfield);
3377         }
3378
3379 skipvar:
3380         if (parser->tok == ';') {
3381             ast_delete(basetype);
3382             if (!parser_next(parser)) {
3383                 parseerror(parser, "error after variable declaration");
3384                 return false;
3385             }
3386             return true;
3387         }
3388
3389         if (parser->tok == ',')
3390             goto another;
3391
3392         if (!var || (!localblock && !nofields && basetype->expression.vtype == TYPE_FIELD)) {
3393             parseerror(parser, "missing comma or semicolon while parsing variables");
3394             break;
3395         }
3396
3397         if (localblock && opts_standard == COMPILER_QCC) {
3398             if (parsewarning(parser, WARN_LOCAL_CONSTANTS,
3399                              "initializing expression turns variable `%s` into a constant in this standard",
3400                              var->name) )
3401             {
3402                 break;
3403             }
3404         }
3405
3406         if (parser->tok != '{') {
3407             if (parser->tok != '=') {
3408                 parseerror(parser, "missing semicolon or initializer");
3409                 break;
3410             }
3411
3412             if (!parser_next(parser)) {
3413                 parseerror(parser, "error parsing initializer");
3414                 break;
3415             }
3416         }
3417         else if (opts_standard == COMPILER_QCC) {
3418             parseerror(parser, "expected '=' before function body in this standard");
3419         }
3420
3421         if (parser->tok == '#') {
3422             ast_function *func;
3423
3424             if (localblock) {
3425                 parseerror(parser, "cannot declare builtins within functions");
3426                 break;
3427             }
3428             if (var->expression.vtype != TYPE_FUNCTION) {
3429                 parseerror(parser, "unexpected builtin number, '%s' is not a function", var->name);
3430                 break;
3431             }
3432             if (!parser_next(parser)) {
3433                 parseerror(parser, "expected builtin number");
3434                 break;
3435             }
3436             if (parser->tok != TOKEN_INTCONST) {
3437                 parseerror(parser, "builtin number must be an integer constant");
3438                 break;
3439             }
3440             if (parser_token(parser)->constval.i <= 0) {
3441                 parseerror(parser, "builtin number must be an integer greater than zero");
3442                 break;
3443             }
3444
3445             func = ast_function_new(ast_ctx(var), var->name, var);
3446             if (!func) {
3447                 parseerror(parser, "failed to allocate function for `%s`", var->name);
3448                 break;
3449             }
3450             vec_push(parser->functions, func);
3451
3452             func->builtin = -parser_token(parser)->constval.i;
3453
3454             if (!parser_next(parser)) {
3455                 parseerror(parser, "expected comma or semicolon");
3456                 ast_function_delete(func);
3457                 var->constval.vfunc = NULL;
3458                 break;
3459             }
3460         }
3461         else if (parser->tok == '{' || parser->tok == '[')
3462         {
3463             if (localblock) {
3464                 parseerror(parser, "cannot declare functions within functions");
3465                 break;
3466             }
3467
3468             if (!parse_function_body(parser, var))
3469                 break;
3470             ast_delete(basetype);
3471             return true;
3472         } else {
3473             ast_expression *cexp;
3474             ast_value      *cval;
3475
3476             cexp = parse_expression_leave(parser, true);
3477             if (!cexp)
3478                 break;
3479
3480             if (!localblock) {
3481                 cval = (ast_value*)cexp;
3482                 if (!ast_istype(cval, ast_value) || !cval->isconst)
3483                     parseerror(parser, "cannot initialize a global constant variable with a non-constant expression");
3484                 else
3485                 {
3486                     var->isconst = true;
3487                     if (cval->expression.vtype == TYPE_STRING)
3488                         var->constval.vstring = parser_strdup(cval->constval.vstring);
3489                     else
3490                         memcpy(&var->constval, &cval->constval, sizeof(var->constval));
3491                     ast_unref(cval);
3492                 }
3493             } else {
3494                 shunt sy = { NULL, NULL };
3495                 vec_push(sy.out, syexp(ast_ctx(var), (ast_expression*)var));
3496                 vec_push(sy.out, syexp(ast_ctx(cexp), (ast_expression*)cexp));
3497                 vec_push(sy.ops, syop(ast_ctx(var), parser->assign_op));
3498                 if (!parser_sy_pop(parser, &sy))
3499                     ast_unref(cexp);
3500                 else {
3501                     if (vec_size(sy.out) != 1 && vec_size(sy.ops) != 0)
3502                         parseerror(parser, "internal error: leaked operands");
3503                     vec_push(localblock->exprs, (ast_expression*)sy.out[0].out);
3504                 }
3505                 vec_free(sy.out);
3506                 vec_free(sy.ops);
3507             }
3508         }
3509
3510 another:
3511         if (parser->tok == ',') {
3512             if (!parser_next(parser)) {
3513                 parseerror(parser, "expected another variable");
3514                 break;
3515             }
3516
3517             if (parser->tok != TOKEN_IDENT) {
3518                 parseerror(parser, "expected another variable");
3519                 break;
3520             }
3521             var = ast_value_copy(basetype);
3522             cleanvar = true;
3523             ast_value_set_name(var, parser_tokval(parser));
3524             if (!parser_next(parser)) {
3525                 parseerror(parser, "error parsing variable declaration");
3526                 break;
3527             }
3528             continue;
3529         }
3530
3531         if (parser->tok != ';') {
3532             parseerror(parser, "missing semicolon after variables");
3533             break;
3534         }
3535
3536         if (!parser_next(parser)) {
3537             parseerror(parser, "parse error after variable declaration");
3538             break;
3539         }
3540
3541         ast_delete(basetype);
3542         return true;
3543     }
3544
3545     if (cleanvar && var)
3546         ast_delete(var);
3547     ast_delete(basetype);
3548     return false;
3549
3550 cleanup:
3551     ast_delete(basetype);
3552     if (cleanvar && var)
3553         ast_delete(var);
3554     if (varent.name) mem_d(varent.name);
3555     if (ve[0].name)  mem_d(ve[0].name);
3556     if (ve[1].name)  mem_d(ve[1].name);
3557     if (ve[2].name)  mem_d(ve[2].name);
3558     if (ve[0].var)   mem_d(ve[0].var);
3559     if (ve[1].var)   mem_d(ve[1].var);
3560     if (ve[2].var)   mem_d(ve[2].var);
3561     return retval;
3562 }
3563
3564 static bool parser_global_statement(parser_t *parser)
3565 {
3566     if (parser->tok == TOKEN_TYPENAME || parser->tok == '.')
3567     {
3568         return parse_variable(parser, NULL, false);
3569     }
3570     else if (parser->tok == TOKEN_KEYWORD)
3571     {
3572         /* handle 'var' and 'const' */
3573         if (!strcmp(parser_tokval(parser), "var")) {
3574             if (!parser_next(parser)) {
3575                 parseerror(parser, "expected variable declaration after 'var'");
3576                 return false;
3577             }
3578             return parse_variable(parser, NULL, true);
3579         }
3580         return false;
3581     }
3582     else if (parser->tok == '$')
3583     {
3584         if (!parser_next(parser)) {
3585             parseerror(parser, "parse error");
3586             return false;
3587         }
3588     }
3589     else
3590     {
3591         parseerror(parser, "unexpected token: %s", parser->lex->tok.value);
3592         return false;
3593     }
3594     return true;
3595 }
3596
3597 static uint16_t progdefs_crc_sum(uint16_t old, const char *str)
3598 {
3599     return util_crc16(old, str, strlen(str));
3600 }
3601
3602 static void progdefs_crc_file(const char *str)
3603 {
3604     /* write to progdefs.h here */
3605     (void)str;
3606 }
3607
3608 static uint16_t progdefs_crc_both(uint16_t old, const char *str)
3609 {
3610     old = progdefs_crc_sum(old, str);
3611     progdefs_crc_file(str);
3612     return old;
3613 }
3614
3615 static void generate_checksum(parser_t *parser)
3616 {
3617     uint16_t crc = 0xFFFF;
3618     size_t i;
3619
3620         crc = progdefs_crc_both(crc, "\n/* file generated by qcc, do not modify */\n\ntypedef struct\n{");
3621         crc = progdefs_crc_sum(crc, "\tint\tpad[28];\n");
3622         /*
3623         progdefs_crc_file("\tint\tpad;\n");
3624         progdefs_crc_file("\tint\tofs_return[3];\n");
3625         progdefs_crc_file("\tint\tofs_parm0[3];\n");
3626         progdefs_crc_file("\tint\tofs_parm1[3];\n");
3627         progdefs_crc_file("\tint\tofs_parm2[3];\n");
3628         progdefs_crc_file("\tint\tofs_parm3[3];\n");
3629         progdefs_crc_file("\tint\tofs_parm4[3];\n");
3630         progdefs_crc_file("\tint\tofs_parm5[3];\n");
3631         progdefs_crc_file("\tint\tofs_parm6[3];\n");
3632         progdefs_crc_file("\tint\tofs_parm7[3];\n");
3633         */
3634         for (i = 0; i < parser->crc_globals; ++i) {
3635             if (!ast_istype(parser->globals[i].var, ast_value))
3636                 continue;
3637             switch (parser->globals[i].var->expression.vtype) {
3638                 case TYPE_FLOAT:    crc = progdefs_crc_both(crc, "\tfloat\t"); break;
3639                 case TYPE_VECTOR:   crc = progdefs_crc_both(crc, "\tvec3_t\t"); break;
3640                 case TYPE_STRING:   crc = progdefs_crc_both(crc, "\tstring_t\t"); break;
3641                 case TYPE_FUNCTION: crc = progdefs_crc_both(crc, "\tfunc_t\t"); break;
3642                 default:
3643                     crc = progdefs_crc_both(crc, "\tint\t");
3644                     break;
3645             }
3646             crc = progdefs_crc_both(crc, parser->globals[i].name);
3647             crc = progdefs_crc_both(crc, ";\n");
3648         }
3649         crc = progdefs_crc_both(crc, "} globalvars_t;\n\ntypedef struct\n{\n");
3650         for (i = 0; i < parser->crc_fields; ++i) {
3651             if (!ast_istype(parser->fields[i].var, ast_value))
3652                 continue;
3653             switch (parser->fields[i].var->expression.next->expression.vtype) {
3654                 case TYPE_FLOAT:    crc = progdefs_crc_both(crc, "\tfloat\t"); break;
3655                 case TYPE_VECTOR:   crc = progdefs_crc_both(crc, "\tvec3_t\t"); break;
3656                 case TYPE_STRING:   crc = progdefs_crc_both(crc, "\tstring_t\t"); break;
3657                 case TYPE_FUNCTION: crc = progdefs_crc_both(crc, "\tfunc_t\t"); break;
3658                 default:
3659                     crc = progdefs_crc_both(crc, "\tint\t");
3660                     break;
3661             }
3662             crc = progdefs_crc_both(crc, parser->fields[i].name);
3663             crc = progdefs_crc_both(crc, ";\n");
3664         }
3665         crc = progdefs_crc_both(crc, "} entvars_t;\n\n");
3666
3667         code_crc = crc;
3668 }
3669
3670 static parser_t *parser;
3671
3672 bool parser_init()
3673 {
3674     size_t i;
3675     parser = (parser_t*)mem_a(sizeof(parser_t));
3676     if (!parser)
3677         return false;
3678
3679     memset(parser, 0, sizeof(*parser));
3680
3681     for (i = 0; i < operator_count; ++i) {
3682         if (operators[i].id == opid1('=')) {
3683             parser->assign_op = operators+i;
3684             break;
3685         }
3686     }
3687     if (!parser->assign_op) {
3688         printf("internal error: initializing parser: failed to find assign operator\n");
3689         mem_d(parser);
3690         return false;
3691     }
3692     return true;
3693 }
3694
3695 bool parser_compile()
3696 {
3697     /* initial lexer/parser state */
3698     parser->lex->flags.noops = true;
3699
3700     if (parser_next(parser))
3701     {
3702         while (parser->tok != TOKEN_EOF && parser->tok < TOKEN_ERROR)
3703         {
3704             if (!parser_global_statement(parser)) {
3705                 if (parser->tok == TOKEN_EOF)
3706                     parseerror(parser, "unexpected eof");
3707                 else if (!parser->errors)
3708                     parseerror(parser, "there have been errors, bailing out");
3709                 lex_close(parser->lex);
3710                 parser->lex = NULL;
3711                 return false;
3712             }
3713         }
3714     } else {
3715         parseerror(parser, "parse error");
3716         lex_close(parser->lex);
3717         parser->lex = NULL;
3718         return false;
3719     }
3720
3721     lex_close(parser->lex);
3722     parser->lex = NULL;
3723
3724     return !parser->errors;
3725 }
3726
3727 bool parser_compile_file(const char *filename)
3728 {
3729     parser->lex = lex_open(filename);
3730     if (!parser->lex) {
3731         con_err("failed to open file \"%s\"\n", filename);
3732         return false;
3733     }
3734     return parser_compile();
3735 }
3736
3737 bool parser_compile_string_len(const char *name, const char *str, size_t len)
3738 {
3739     parser->lex = lex_open_string(str, len, name);
3740     if (!parser->lex) {
3741         con_err("failed to create lexer for string \"%s\"\n", name);
3742         return false;
3743     }
3744     return parser_compile();
3745 }
3746
3747 bool parser_compile_string(const char *name, const char *str)
3748 {
3749     parser->lex = lex_open_string(str, strlen(str), name);
3750     if (!parser->lex) {
3751         con_err("failed to create lexer for string \"%s\"\n", name);
3752         return false;
3753     }
3754     return parser_compile();
3755 }
3756
3757 void parser_cleanup()
3758 {
3759     size_t i;
3760     for (i = 0; i < vec_size(parser->accessors); ++i) {
3761         ast_delete(parser->accessors[i]->constval.vfunc);
3762         parser->accessors[i]->constval.vfunc = NULL;
3763         ast_delete(parser->accessors[i]);
3764     }
3765     for (i = 0; i < vec_size(parser->functions); ++i) {
3766         ast_delete(parser->functions[i]);
3767     }
3768     for (i = 0; i < vec_size(parser->imm_vector); ++i) {
3769         ast_delete(parser->imm_vector[i]);
3770     }
3771     for (i = 0; i < vec_size(parser->imm_string); ++i) {
3772         ast_delete(parser->imm_string[i]);
3773     }
3774     for (i = 0; i < vec_size(parser->imm_float); ++i) {
3775         ast_delete(parser->imm_float[i]);
3776     }
3777     for (i = 0; i < vec_size(parser->fields); ++i) {
3778         ast_delete(parser->fields[i].var);
3779         mem_d(parser->fields[i].name);
3780     }
3781     for (i = 0; i < vec_size(parser->globals); ++i) {
3782         ast_delete(parser->globals[i].var);
3783         mem_d(parser->globals[i].name);
3784     }
3785     vec_free(parser->accessors);
3786     vec_free(parser->functions);
3787     vec_free(parser->imm_vector);
3788     vec_free(parser->imm_string);
3789     vec_free(parser->imm_float);
3790     vec_free(parser->globals);
3791     vec_free(parser->fields);
3792     vec_free(parser->locals);
3793
3794     mem_d(parser);
3795 }
3796
3797 bool parser_finish(const char *output)
3798 {
3799     size_t i;
3800     ir_builder *ir;
3801     bool retval = true;
3802
3803     if (!parser->errors)
3804     {
3805         ir = ir_builder_new("gmqcc_out");
3806         if (!ir) {
3807             con_out("failed to allocate builder\n");
3808             return false;
3809         }
3810
3811         for (i = 0; i < vec_size(parser->fields); ++i) {
3812             ast_value *field;
3813             bool isconst;
3814             if (!ast_istype(parser->fields[i].var, ast_value))
3815                 continue;
3816             field = (ast_value*)parser->fields[i].var;
3817             isconst = field->isconst;
3818             field->isconst = false;
3819             if (!ast_global_codegen((ast_value*)field, ir, true)) {
3820                 con_out("failed to generate field %s\n", field->name);
3821                 ir_builder_delete(ir);
3822                 return false;
3823             }
3824             if (isconst) {
3825                 ir_value *ifld;
3826                 ast_expression *subtype;
3827                 field->isconst = true;
3828                 subtype = field->expression.next;
3829                 ifld = ir_builder_create_field(ir, field->name, subtype->expression.vtype);
3830                 if (subtype->expression.vtype == TYPE_FIELD)
3831                     ifld->fieldtype = subtype->expression.next->expression.vtype;
3832                 else if (subtype->expression.vtype == TYPE_FUNCTION)
3833                     ifld->outtype = subtype->expression.next->expression.vtype;
3834                 (void)!ir_value_set_field(field->ir_v, ifld);
3835             }
3836         }
3837         for (i = 0; i < vec_size(parser->globals); ++i) {
3838             ast_value *asvalue;
3839             if (!ast_istype(parser->globals[i].var, ast_value))
3840                 continue;
3841             asvalue = (ast_value*)(parser->globals[i].var);
3842             if (!asvalue->uses && !asvalue->isconst && asvalue->expression.vtype != TYPE_FUNCTION) {
3843                 if (strcmp(asvalue->name, "end_sys_globals") &&
3844                     strcmp(asvalue->name, "end_sys_fields"))
3845                 {
3846                     retval = retval && !genwarning(ast_ctx(asvalue), WARN_UNUSED_VARIABLE,
3847                                                    "unused global: `%s`", asvalue->name);
3848                 }
3849             }
3850             if (!ast_global_codegen(asvalue, ir, false)) {
3851                 con_out("failed to generate global %s\n", parser->globals[i].name);
3852                 ir_builder_delete(ir);
3853                 return false;
3854             }
3855         }
3856         for (i = 0; i < vec_size(parser->imm_float); ++i) {
3857             if (!ast_global_codegen(parser->imm_float[i], ir, false)) {
3858                 con_out("failed to generate global %s\n", parser->imm_float[i]->name);
3859                 ir_builder_delete(ir);
3860                 return false;
3861             }
3862         }
3863         for (i = 0; i < vec_size(parser->imm_string); ++i) {
3864             if (!ast_global_codegen(parser->imm_string[i], ir, false)) {
3865                 con_out("failed to generate global %s\n", parser->imm_string[i]->name);
3866                 ir_builder_delete(ir);
3867                 return false;
3868             }
3869         }
3870         for (i = 0; i < vec_size(parser->imm_vector); ++i) {
3871             if (!ast_global_codegen(parser->imm_vector[i], ir, false)) {
3872                 con_out("failed to generate global %s\n", parser->imm_vector[i]->name);
3873                 ir_builder_delete(ir);
3874                 return false;
3875             }
3876         }
3877         for (i = 0; i < vec_size(parser->globals); ++i) {
3878             ast_value *asvalue;
3879             if (!ast_istype(parser->globals[i].var, ast_value))
3880                 continue;
3881             asvalue = (ast_value*)(parser->globals[i].var);
3882             if (asvalue->setter) {
3883                 if (!ast_global_codegen(asvalue->setter, ir, false) ||
3884                     !ast_function_codegen(asvalue->setter->constval.vfunc, ir) ||
3885                     !ir_function_finalize(asvalue->setter->constval.vfunc->ir_func))
3886                 {
3887                     printf("failed to generate setter for %s\n", parser->globals[i].name);
3888                     ir_builder_delete(ir);
3889                     return false;
3890                 }
3891             }
3892             if (asvalue->getter) {
3893                 if (!ast_global_codegen(asvalue->getter, ir, false) ||
3894                     !ast_function_codegen(asvalue->getter->constval.vfunc, ir) ||
3895                     !ir_function_finalize(asvalue->getter->constval.vfunc->ir_func))
3896                 {
3897                     printf("failed to generate getter for %s\n", parser->globals[i].name);
3898                     ir_builder_delete(ir);
3899                     return false;
3900                 }
3901             }
3902         }
3903         for (i = 0; i < vec_size(parser->fields); ++i) {
3904             ast_value *asvalue;
3905             asvalue = (ast_value*)(parser->fields[i].var->expression.next);
3906
3907             if (!ast_istype((ast_expression*)asvalue, ast_value))
3908                 continue;
3909             if (asvalue->expression.vtype != TYPE_ARRAY)
3910                 continue;
3911             if (asvalue->setter) {
3912                 if (!ast_global_codegen(asvalue->setter, ir, false) ||
3913                     !ast_function_codegen(asvalue->setter->constval.vfunc, ir) ||
3914                     !ir_function_finalize(asvalue->setter->constval.vfunc->ir_func))
3915                 {
3916                     printf("failed to generate setter for %s\n", parser->fields[i].name);
3917                     ir_builder_delete(ir);
3918                     return false;
3919                 }
3920             }
3921             if (asvalue->getter) {
3922                 if (!ast_global_codegen(asvalue->getter, ir, false) ||
3923                     !ast_function_codegen(asvalue->getter->constval.vfunc, ir) ||
3924                     !ir_function_finalize(asvalue->getter->constval.vfunc->ir_func))
3925                 {
3926                     printf("failed to generate getter for %s\n", parser->fields[i].name);
3927                     ir_builder_delete(ir);
3928                     return false;
3929                 }
3930             }
3931         }
3932         for (i = 0; i < vec_size(parser->functions); ++i) {
3933             if (!ast_function_codegen(parser->functions[i], ir)) {
3934                 con_out("failed to generate function %s\n", parser->functions[i]->name);
3935                 ir_builder_delete(ir);
3936                 return false;
3937             }
3938         }
3939         if (opts_dump)
3940             ir_builder_dump(ir, con_out);
3941         for (i = 0; i < vec_size(parser->functions); ++i) {
3942             if (!ir_function_finalize(parser->functions[i]->ir_func)) {
3943                 con_out("failed to finalize function %s\n", parser->functions[i]->name);
3944                 ir_builder_delete(ir);
3945                 return false;
3946             }
3947         }
3948
3949         if (retval) {
3950             if (opts_dumpfin)
3951                 ir_builder_dump(ir, con_out);
3952
3953             generate_checksum(parser);
3954
3955             if (!ir_builder_generate(ir, output)) {
3956                 con_out("*** failed to generate output file\n");
3957                 ir_builder_delete(ir);
3958                 return false;
3959             }
3960         }
3961
3962         ir_builder_delete(ir);
3963         return retval;
3964     }
3965
3966     con_out("*** there were compile errors\n");
3967     return false;
3968 }