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