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