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