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