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