]> de.git.xonotic.org Git - xonotic/gmqcc.git/blob - parser.c
don't just store a 'bool constant' in the ast/ir, store the complete qualifier: ...
[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 is_const_var, 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             vec_push(sy.out, syexp(parser_ctx(parser), var));
1418             DEBUGSHUNTDO(con_out("push %s\n", parser_tokval(parser)));
1419         }
1420         else if (parser->tok == TOKEN_FLOATCONST) {
1421             ast_value *val;
1422             if (wantop) {
1423                 parseerror(parser, "expected operator or end of statement, got constant");
1424                 goto onerr;
1425             }
1426             wantop = true;
1427             val = parser_const_float(parser, (parser_token(parser)->constval.f));
1428             if (!val)
1429                 return false;
1430             vec_push(sy.out, syexp(parser_ctx(parser), (ast_expression*)val));
1431             DEBUGSHUNTDO(con_out("push %g\n", parser_token(parser)->constval.f));
1432         }
1433         else if (parser->tok == TOKEN_INTCONST || parser->tok == TOKEN_CHARCONST) {
1434             ast_value *val;
1435             if (wantop) {
1436                 parseerror(parser, "expected operator or end of statement, got constant");
1437                 goto onerr;
1438             }
1439             wantop = true;
1440             val = parser_const_float(parser, (double)(parser_token(parser)->constval.i));
1441             if (!val)
1442                 return false;
1443             vec_push(sy.out, syexp(parser_ctx(parser), (ast_expression*)val));
1444             DEBUGSHUNTDO(con_out("push %i\n", parser_token(parser)->constval.i));
1445         }
1446         else if (parser->tok == TOKEN_STRINGCONST) {
1447             ast_value *val;
1448             if (wantop) {
1449                 parseerror(parser, "expected operator or end of statement, got constant");
1450                 goto onerr;
1451             }
1452             wantop = true;
1453             val = parser_const_string(parser, parser_tokval(parser), false);
1454             if (!val)
1455                 return false;
1456             vec_push(sy.out, syexp(parser_ctx(parser), (ast_expression*)val));
1457             DEBUGSHUNTDO(con_out("push string\n"));
1458         }
1459         else if (parser->tok == TOKEN_VECTORCONST) {
1460             ast_value *val;
1461             if (wantop) {
1462                 parseerror(parser, "expected operator or end of statement, got constant");
1463                 goto onerr;
1464             }
1465             wantop = true;
1466             val = parser_const_vector(parser, parser_token(parser)->constval.v);
1467             if (!val)
1468                 return false;
1469             vec_push(sy.out, syexp(parser_ctx(parser), (ast_expression*)val));
1470             DEBUGSHUNTDO(con_out("push '%g %g %g'\n",
1471                                 parser_token(parser)->constval.v.x,
1472                                 parser_token(parser)->constval.v.y,
1473                                 parser_token(parser)->constval.v.z));
1474         }
1475         else if (parser->tok == '(') {
1476             parseerror(parser, "internal error: '(' should be classified as operator");
1477             goto onerr;
1478         }
1479         else if (parser->tok == '[') {
1480             parseerror(parser, "internal error: '[' should be classified as operator");
1481             goto onerr;
1482         }
1483         else if (parser->tok == ')') {
1484             if (wantop) {
1485                 DEBUGSHUNTDO(con_out("do[op] )\n"));
1486                 --parens;
1487                 if (parens < 0)
1488                     break;
1489                 /* we do expect an operator next */
1490                 /* closing an opening paren */
1491                 if (!parser_close_paren(parser, &sy, false))
1492                     goto onerr;
1493             } else {
1494                 DEBUGSHUNTDO(con_out("do[nop] )\n"));
1495                 --parens;
1496                 if (parens < 0)
1497                     break;
1498                 /* allowed for function calls */
1499                 if (!parser_close_paren(parser, &sy, true))
1500                     goto onerr;
1501             }
1502             wantop = true;
1503         }
1504         else if (parser->tok == ']') {
1505             if (!wantop)
1506                 parseerror(parser, "operand expected");
1507             --parens;
1508             if (parens < 0)
1509                 break;
1510             if (!parser_close_paren(parser, &sy, false))
1511                 goto onerr;
1512             wantop = true;
1513         }
1514         else if (parser->tok != TOKEN_OPERATOR) {
1515             if (wantop) {
1516                 parseerror(parser, "expected operator or end of statement");
1517                 goto onerr;
1518             }
1519             break;
1520         }
1521         else
1522         {
1523             /* classify the operator */
1524             const oper_info *op;
1525             const oper_info *olast = NULL;
1526             size_t o;
1527             for (o = 0; o < operator_count; ++o) {
1528                 if ((!(operators[o].flags & OP_PREFIX) == wantop) &&
1529                     /* !(operators[o].flags & OP_SUFFIX) && / * remove this */
1530                     !strcmp(parser_tokval(parser), operators[o].op))
1531                 {
1532                     break;
1533                 }
1534             }
1535             if (o == operator_count) {
1536                 /* no operator found... must be the end of the statement */
1537                 break;
1538             }
1539             /* found an operator */
1540             op = &operators[o];
1541
1542             /* when declaring variables, a comma starts a new variable */
1543             if (op->id == opid1(',') && !parens && stopatcomma) {
1544                 /* fixup the token */
1545                 parser->tok = ',';
1546                 break;
1547             }
1548
1549             /* a colon without a pervious question mark cannot be a ternary */
1550             if (!ternaries && op->id == opid2(':','?')) {
1551                 parser->tok = ':';
1552                 break;
1553             }
1554
1555             if (vec_size(sy.ops) && !vec_last(sy.ops).paren)
1556                 olast = &operators[vec_last(sy.ops).etype-1];
1557
1558             while (olast && (
1559                     (op->prec < olast->prec) ||
1560                     (op->assoc == ASSOC_LEFT && op->prec <= olast->prec) ) )
1561             {
1562                 if (!parser_sy_pop(parser, &sy))
1563                     goto onerr;
1564                 if (vec_size(sy.ops) && !vec_last(sy.ops).paren)
1565                     olast = &operators[vec_last(sy.ops).etype-1];
1566                 else
1567                     olast = NULL;
1568             }
1569
1570             if (op->id == opid1('.') && opts_standard == COMPILER_GMQCC) {
1571                 /* for gmqcc standard: open up the namespace of the previous type */
1572                 ast_expression *prevex = vec_last(sy.out).out;
1573                 if (!prevex) {
1574                     parseerror(parser, "unexpected member operator");
1575                     goto onerr;
1576                 }
1577                 if (prevex->expression.vtype == TYPE_ENTITY)
1578                     parser->memberof = TYPE_ENTITY;
1579                 else if (prevex->expression.vtype == TYPE_VECTOR)
1580                     parser->memberof = TYPE_VECTOR;
1581                 else {
1582                     parseerror(parser, "type error: type has no members");
1583                     goto onerr;
1584                 }
1585                 gotmemberof = true;
1586             }
1587
1588             if (op->id == opid1('(')) {
1589                 if (wantop) {
1590                     size_t sycount = vec_size(sy.out);
1591                     DEBUGSHUNTDO(con_out("push [op] (\n"));
1592                     ++parens;
1593                     /* we expected an operator, this is the function-call operator */
1594                     vec_push(sy.ops, syparen(parser_ctx(parser), SY_PAREN_FUNC, sycount-1));
1595                 } else {
1596                     ++parens;
1597                     vec_push(sy.ops, syparen(parser_ctx(parser), SY_PAREN_EXPR, 0));
1598                     DEBUGSHUNTDO(con_out("push [nop] (\n"));
1599                 }
1600                 wantop = false;
1601             } else if (op->id == opid1('[')) {
1602                 if (!wantop) {
1603                     parseerror(parser, "unexpected array subscript");
1604                     goto onerr;
1605                 }
1606                 ++parens;
1607                 /* push both the operator and the paren, this makes life easier */
1608                 vec_push(sy.ops, syop(parser_ctx(parser), op));
1609                 vec_push(sy.ops, syparen(parser_ctx(parser), SY_PAREN_INDEX, 0));
1610                 wantop = false;
1611             } else if (op->id == opid2('?',':')) {
1612                 wantop = false;
1613                 vec_push(sy.ops, syop(parser_ctx(parser), op));
1614                 wantop = false;
1615                 --ternaries;
1616             } else if (op->id == opid2(':','?')) {
1617                 /* we don't push this operator */
1618                 wantop = false;
1619                 ++ternaries;
1620             } else {
1621                 DEBUGSHUNTDO(con_out("push operator %s\n", op->op));
1622                 vec_push(sy.ops, syop(parser_ctx(parser), op));
1623                 wantop = !!(op->flags & OP_SUFFIX);
1624             }
1625         }
1626         if (!parser_next(parser)) {
1627             goto onerr;
1628         }
1629         if (parser->tok == ';' ||
1630             (!parens && parser->tok == ']'))
1631         {
1632             break;
1633         }
1634     }
1635
1636     while (vec_size(sy.ops)) {
1637         if (!parser_sy_pop(parser, &sy))
1638             goto onerr;
1639     }
1640
1641     parser->lex->flags.noops = true;
1642     if (!vec_size(sy.out)) {
1643         parseerror(parser, "empty expression");
1644         expr = NULL;
1645     } else
1646         expr = sy.out[0].out;
1647     vec_free(sy.out);
1648     vec_free(sy.ops);
1649     DEBUGSHUNTDO(con_out("shunt done\n"));
1650     return expr;
1651
1652 onerr:
1653     parser->lex->flags.noops = true;
1654     vec_free(sy.out);
1655     vec_free(sy.ops);
1656     return NULL;
1657 }
1658
1659 static ast_expression* parse_expression(parser_t *parser, bool stopatcomma)
1660 {
1661     ast_expression *e = parse_expression_leave(parser, stopatcomma);
1662     if (!e)
1663         return NULL;
1664     if (!parser_next(parser)) {
1665         ast_delete(e);
1666         return NULL;
1667     }
1668     return e;
1669 }
1670
1671 static void parser_enterblock(parser_t *parser)
1672 {
1673     vec_push(parser->variables, util_htnew(PARSER_HT_SIZE));
1674     vec_push(parser->_blocklocals, vec_size(parser->_locals));
1675     vec_push(parser->typedefs, util_htnew(TYPEDEF_HT_SIZE));
1676     vec_push(parser->_blocktypedefs, vec_size(parser->_typedefs));
1677 }
1678
1679 static bool parser_leaveblock(parser_t *parser)
1680 {
1681     bool   rv = true;
1682     size_t locals, typedefs;
1683
1684     if (vec_size(parser->variables) <= PARSER_HT_LOCALS) {
1685         parseerror(parser, "internal error: parser_leaveblock with no block");
1686         return false;
1687     }
1688
1689     util_htdel(vec_last(parser->variables));
1690     vec_pop(parser->variables);
1691     if (!vec_size(parser->_blocklocals)) {
1692         parseerror(parser, "internal error: parser_leaveblock with no block (2)");
1693         return false;
1694     }
1695
1696     locals = vec_last(parser->_blocklocals);
1697     vec_pop(parser->_blocklocals);
1698     while (vec_size(parser->_locals) != locals) {
1699         ast_expression *e = vec_last(parser->_locals);
1700         ast_value      *v = (ast_value*)e;
1701         vec_pop(parser->_locals);
1702         if (ast_istype(e, ast_value) && !v->uses) {
1703             if (parsewarning(parser, WARN_UNUSED_VARIABLE, "unused variable: `%s`", v->name))
1704                 rv = false;
1705         }
1706     }
1707
1708     typedefs = vec_last(parser->_blocktypedefs);
1709     while (vec_size(parser->_typedefs) != typedefs) {
1710         ast_delete(vec_last(parser->_typedefs));
1711         vec_pop(parser->_typedefs);
1712     }
1713     util_htdel(vec_last(parser->typedefs));
1714     vec_pop(parser->typedefs);
1715
1716     return rv;
1717 }
1718
1719 static void parser_addlocal(parser_t *parser, const char *name, ast_expression *e)
1720 {
1721     vec_push(parser->_locals, e);
1722     util_htset(vec_last(parser->variables), name, (void*)e);
1723 }
1724
1725 static bool parse_if(parser_t *parser, ast_block *block, ast_expression **out)
1726 {
1727     ast_ifthen *ifthen;
1728     ast_expression *cond, *ontrue, *onfalse = NULL;
1729     bool ifnot = false;
1730
1731     lex_ctx ctx = parser_ctx(parser);
1732
1733     (void)block; /* not touching */
1734
1735     /* skip the 'if', parse an optional 'not' and check for an opening paren */
1736     if (!parser_next(parser)) {
1737         parseerror(parser, "expected condition or 'not'");
1738         return false;
1739     }
1740     if (parser->tok == TOKEN_IDENT && !strcmp(parser_tokval(parser), "not")) {
1741         ifnot = true;
1742         if (!parser_next(parser)) {
1743             parseerror(parser, "expected condition in parenthesis");
1744             return false;
1745         }
1746     }
1747     if (parser->tok != '(') {
1748         parseerror(parser, "expected 'if' condition in parenthesis");
1749         return false;
1750     }
1751     /* parse into the expression */
1752     if (!parser_next(parser)) {
1753         parseerror(parser, "expected 'if' condition after opening paren");
1754         return false;
1755     }
1756     /* parse the condition */
1757     cond = parse_expression_leave(parser, false);
1758     if (!cond)
1759         return false;
1760     /* closing paren */
1761     if (parser->tok != ')') {
1762         parseerror(parser, "expected closing paren after 'if' condition");
1763         ast_delete(cond);
1764         return false;
1765     }
1766     /* parse into the 'then' branch */
1767     if (!parser_next(parser)) {
1768         parseerror(parser, "expected statement for on-true branch of 'if'");
1769         ast_delete(cond);
1770         return false;
1771     }
1772     ontrue = parse_statement_or_block(parser);
1773     if (!ontrue) {
1774         ast_delete(cond);
1775         return false;
1776     }
1777     /* check for an else */
1778     if (!strcmp(parser_tokval(parser), "else")) {
1779         /* parse into the 'else' branch */
1780         if (!parser_next(parser)) {
1781             parseerror(parser, "expected on-false branch after 'else'");
1782             ast_delete(ontrue);
1783             ast_delete(cond);
1784             return false;
1785         }
1786         onfalse = parse_statement_or_block(parser);
1787         if (!onfalse) {
1788             ast_delete(ontrue);
1789             ast_delete(cond);
1790             return false;
1791         }
1792     }
1793
1794     if (ifnot)
1795         ifthen = ast_ifthen_new(ctx, cond, onfalse, ontrue);
1796     else
1797         ifthen = ast_ifthen_new(ctx, cond, ontrue, onfalse);
1798     *out = (ast_expression*)ifthen;
1799     return true;
1800 }
1801
1802 static bool parse_while(parser_t *parser, ast_block *block, ast_expression **out)
1803 {
1804     ast_loop *aloop;
1805     ast_expression *cond, *ontrue;
1806
1807     lex_ctx ctx = parser_ctx(parser);
1808
1809     (void)block; /* not touching */
1810
1811     /* skip the 'while' and check for opening paren */
1812     if (!parser_next(parser) || parser->tok != '(') {
1813         parseerror(parser, "expected 'while' condition in parenthesis");
1814         return false;
1815     }
1816     /* parse into the expression */
1817     if (!parser_next(parser)) {
1818         parseerror(parser, "expected 'while' condition after opening paren");
1819         return false;
1820     }
1821     /* parse the condition */
1822     cond = parse_expression_leave(parser, false);
1823     if (!cond)
1824         return false;
1825     /* closing paren */
1826     if (parser->tok != ')') {
1827         parseerror(parser, "expected closing paren after 'while' condition");
1828         ast_delete(cond);
1829         return false;
1830     }
1831     /* parse into the 'then' branch */
1832     if (!parser_next(parser)) {
1833         parseerror(parser, "expected while-loop body");
1834         ast_delete(cond);
1835         return false;
1836     }
1837     ontrue = parse_statement_or_block(parser);
1838     if (!ontrue) {
1839         ast_delete(cond);
1840         return false;
1841     }
1842
1843     aloop = ast_loop_new(ctx, NULL, cond, NULL, NULL, ontrue);
1844     *out = (ast_expression*)aloop;
1845     return true;
1846 }
1847
1848 static bool parse_dowhile(parser_t *parser, ast_block *block, ast_expression **out)
1849 {
1850     ast_loop *aloop;
1851     ast_expression *cond, *ontrue;
1852
1853     lex_ctx ctx = parser_ctx(parser);
1854
1855     (void)block; /* not touching */
1856
1857     /* skip the 'do' and get the body */
1858     if (!parser_next(parser)) {
1859         parseerror(parser, "expected loop body");
1860         return false;
1861     }
1862     ontrue = parse_statement_or_block(parser);
1863     if (!ontrue)
1864         return false;
1865
1866     /* expect the "while" */
1867     if (parser->tok != TOKEN_KEYWORD ||
1868         strcmp(parser_tokval(parser), "while"))
1869     {
1870         parseerror(parser, "expected 'while' and condition");
1871         ast_delete(ontrue);
1872         return false;
1873     }
1874
1875     /* skip the 'while' and check for opening paren */
1876     if (!parser_next(parser) || parser->tok != '(') {
1877         parseerror(parser, "expected 'while' condition in parenthesis");
1878         ast_delete(ontrue);
1879         return false;
1880     }
1881     /* parse into the expression */
1882     if (!parser_next(parser)) {
1883         parseerror(parser, "expected 'while' condition after opening paren");
1884         ast_delete(ontrue);
1885         return false;
1886     }
1887     /* parse the condition */
1888     cond = parse_expression_leave(parser, false);
1889     if (!cond)
1890         return false;
1891     /* closing paren */
1892     if (parser->tok != ')') {
1893         parseerror(parser, "expected closing paren after 'while' condition");
1894         ast_delete(ontrue);
1895         ast_delete(cond);
1896         return false;
1897     }
1898     /* parse on */
1899     if (!parser_next(parser) || parser->tok != ';') {
1900         parseerror(parser, "expected semicolon after condition");
1901         ast_delete(ontrue);
1902         ast_delete(cond);
1903         return false;
1904     }
1905
1906     if (!parser_next(parser)) {
1907         parseerror(parser, "parse error");
1908         ast_delete(ontrue);
1909         ast_delete(cond);
1910         return false;
1911     }
1912
1913     aloop = ast_loop_new(ctx, NULL, NULL, cond, NULL, ontrue);
1914     *out = (ast_expression*)aloop;
1915     return true;
1916 }
1917
1918 static bool parse_for(parser_t *parser, ast_block *block, ast_expression **out)
1919 {
1920     ast_loop       *aloop;
1921     ast_expression *initexpr, *cond, *increment, *ontrue;
1922     ast_value      *typevar;
1923     bool   retval = true;
1924
1925     lex_ctx ctx = parser_ctx(parser);
1926
1927     parser_enterblock(parser);
1928
1929     initexpr  = NULL;
1930     cond      = NULL;
1931     increment = NULL;
1932     ontrue    = NULL;
1933
1934     /* skip the 'while' and check for opening paren */
1935     if (!parser_next(parser) || parser->tok != '(') {
1936         parseerror(parser, "expected 'for' expressions in parenthesis");
1937         goto onerr;
1938     }
1939     /* parse into the expression */
1940     if (!parser_next(parser)) {
1941         parseerror(parser, "expected 'for' initializer after opening paren");
1942         goto onerr;
1943     }
1944
1945     typevar = NULL;
1946     if (parser->tok == TOKEN_IDENT)
1947         typevar = parser_find_typedef(parser, parser_tokval(parser), 0);
1948
1949     if (typevar || parser->tok == TOKEN_TYPENAME) {
1950         if (opts_standard != COMPILER_GMQCC) {
1951             if (parsewarning(parser, WARN_EXTENSIONS,
1952                              "current standard does not allow variable declarations in for-loop initializers"))
1953                 goto onerr;
1954         }
1955         if (!parse_variable(parser, block, true, CV_VAR, typevar))
1956             goto onerr;
1957     }
1958     else if (parser->tok != ';')
1959     {
1960         initexpr = parse_expression_leave(parser, false);
1961         if (!initexpr)
1962             goto onerr;
1963     }
1964
1965     /* move on to condition */
1966     if (parser->tok != ';') {
1967         parseerror(parser, "expected semicolon after for-loop initializer");
1968         goto onerr;
1969     }
1970     if (!parser_next(parser)) {
1971         parseerror(parser, "expected for-loop condition");
1972         goto onerr;
1973     }
1974
1975     /* parse the condition */
1976     if (parser->tok != ';') {
1977         cond = parse_expression_leave(parser, false);
1978         if (!cond)
1979             goto onerr;
1980     }
1981
1982     /* move on to incrementor */
1983     if (parser->tok != ';') {
1984         parseerror(parser, "expected semicolon after for-loop initializer");
1985         goto onerr;
1986     }
1987     if (!parser_next(parser)) {
1988         parseerror(parser, "expected for-loop condition");
1989         goto onerr;
1990     }
1991
1992     /* parse the incrementor */
1993     if (parser->tok != ')') {
1994         increment = parse_expression_leave(parser, false);
1995         if (!increment)
1996             goto onerr;
1997         if (!ast_side_effects(increment)) {
1998             if (genwarning(ast_ctx(increment), WARN_EFFECTLESS_STATEMENT, "statement has no effect"))
1999                 goto onerr;
2000         }
2001     }
2002
2003     /* closing paren */
2004     if (parser->tok != ')') {
2005         parseerror(parser, "expected closing paren after 'for-loop' incrementor");
2006         goto onerr;
2007     }
2008     /* parse into the 'then' branch */
2009     if (!parser_next(parser)) {
2010         parseerror(parser, "expected for-loop body");
2011         goto onerr;
2012     }
2013     ontrue = parse_statement_or_block(parser);
2014     if (!ontrue) {
2015         goto onerr;
2016     }
2017
2018     aloop = ast_loop_new(ctx, initexpr, cond, NULL, increment, ontrue);
2019     *out = (ast_expression*)aloop;
2020
2021     if (!parser_leaveblock(parser))
2022         retval = false;
2023     return retval;
2024 onerr:
2025     if (initexpr)  ast_delete(initexpr);
2026     if (cond)      ast_delete(cond);
2027     if (increment) ast_delete(increment);
2028     (void)!parser_leaveblock(parser);
2029     return false;
2030 }
2031
2032 static bool parse_return(parser_t *parser, ast_block *block, ast_expression **out)
2033 {
2034     ast_expression *exp = NULL;
2035     ast_return     *ret = NULL;
2036     ast_value      *expected = parser->function->vtype;
2037
2038     (void)block; /* not touching */
2039
2040     if (!parser_next(parser)) {
2041         parseerror(parser, "expected return expression");
2042         return false;
2043     }
2044
2045     if (parser->tok != ';') {
2046         exp = parse_expression(parser, false);
2047         if (!exp)
2048             return false;
2049
2050         if (exp->expression.vtype != expected->expression.next->expression.vtype) {
2051             parseerror(parser, "return with invalid expression");
2052         }
2053
2054         ret = ast_return_new(exp->expression.node.context, exp);
2055         if (!ret) {
2056             ast_delete(exp);
2057             return false;
2058         }
2059     } else {
2060         if (!parser_next(parser))
2061             parseerror(parser, "parse error");
2062         if (expected->expression.next->expression.vtype != TYPE_VOID) {
2063             if (opts_standard != COMPILER_GMQCC)
2064                 (void)!parsewarning(parser, WARN_MISSING_RETURN_VALUES, "return without value");
2065             else
2066                 parseerror(parser, "return without value");
2067         }
2068         ret = ast_return_new(parser_ctx(parser), NULL);
2069     }
2070     *out = (ast_expression*)ret;
2071     return true;
2072 }
2073
2074 static bool parse_break_continue(parser_t *parser, ast_block *block, ast_expression **out, bool is_continue)
2075 {
2076     lex_ctx ctx = parser_ctx(parser);
2077
2078     (void)block; /* not touching */
2079
2080     if (!parser_next(parser) || parser->tok != ';') {
2081         parseerror(parser, "expected semicolon");
2082         return false;
2083     }
2084
2085     if (!parser_next(parser))
2086         parseerror(parser, "parse error");
2087
2088     *out = (ast_expression*)ast_breakcont_new(ctx, is_continue);
2089     return true;
2090 }
2091
2092 static bool parse_switch(parser_t *parser, ast_block *block, ast_expression **out)
2093 {
2094     ast_expression *operand;
2095     ast_value      *opval;
2096     ast_switch     *switchnode;
2097     ast_switch_case swcase;
2098
2099     lex_ctx ctx = parser_ctx(parser);
2100
2101     (void)block; /* not touching */
2102     (void)opval;
2103
2104     /* parse over the opening paren */
2105     if (!parser_next(parser) || parser->tok != '(') {
2106         parseerror(parser, "expected switch operand in parenthesis");
2107         return false;
2108     }
2109
2110     /* parse into the expression */
2111     if (!parser_next(parser)) {
2112         parseerror(parser, "expected switch operand");
2113         return false;
2114     }
2115     /* parse the operand */
2116     operand = parse_expression_leave(parser, false);
2117     if (!operand)
2118         return false;
2119
2120     switchnode = ast_switch_new(ctx, operand);
2121
2122     /* closing paren */
2123     if (parser->tok != ')') {
2124         ast_delete(switchnode);
2125         parseerror(parser, "expected closing paren after 'switch' operand");
2126         return false;
2127     }
2128
2129     /* parse over the opening paren */
2130     if (!parser_next(parser) || parser->tok != '{') {
2131         ast_delete(switchnode);
2132         parseerror(parser, "expected list of cases");
2133         return false;
2134     }
2135
2136     if (!parser_next(parser)) {
2137         ast_delete(switchnode);
2138         parseerror(parser, "expected 'case' or 'default'");
2139         return false;
2140     }
2141
2142     /* case list! */
2143     while (parser->tok != '}') {
2144         ast_block *caseblock;
2145
2146         if (parser->tok != TOKEN_KEYWORD) {
2147             ast_delete(switchnode);
2148             parseerror(parser, "expected 'case' or 'default'");
2149             return false;
2150         }
2151         if (!strcmp(parser_tokval(parser), "case")) {
2152             if (!parser_next(parser)) {
2153                 ast_delete(switchnode);
2154                 parseerror(parser, "expected expression for case");
2155                 return false;
2156             }
2157             swcase.value = parse_expression_leave(parser, false);
2158             if (!swcase.value) {
2159                 ast_delete(switchnode);
2160                 parseerror(parser, "expected expression for case");
2161                 return false;
2162             }
2163             if (!OPTS_FLAG(RELAXED_SWITCH)) {
2164                 opval = (ast_value*)swcase.value;
2165                 if (!ast_istype(swcase.value, ast_value)) { /* || opval->cvq != CV_CONST) { */
2166                     parseerror(parser, "case on non-constant values need to be explicitly enabled via -frelaxed-switch");
2167                     ast_unref(operand);
2168                     return false;
2169                 }
2170             }
2171         }
2172         else if (!strcmp(parser_tokval(parser), "default")) {
2173             swcase.value = NULL;
2174             if (!parser_next(parser)) {
2175                 ast_delete(switchnode);
2176                 parseerror(parser, "expected colon");
2177                 return false;
2178             }
2179         }
2180
2181         /* Now the colon and body */
2182         if (parser->tok != ':') {
2183             if (swcase.value) ast_unref(swcase.value);
2184             ast_delete(switchnode);
2185             parseerror(parser, "expected colon");
2186             return false;
2187         }
2188
2189         if (!parser_next(parser)) {
2190             if (swcase.value) ast_unref(swcase.value);
2191             ast_delete(switchnode);
2192             parseerror(parser, "expected statements or case");
2193             return false;
2194         }
2195         caseblock = ast_block_new(parser_ctx(parser));
2196         if (!caseblock) {
2197             if (swcase.value) ast_unref(swcase.value);
2198             ast_delete(switchnode);
2199             return false;
2200         }
2201         swcase.code = (ast_expression*)caseblock;
2202         vec_push(switchnode->cases, swcase);
2203         while (true) {
2204             ast_expression *expr;
2205             if (parser->tok == '}')
2206                 break;
2207             if (parser->tok == TOKEN_KEYWORD) {
2208                 if (!strcmp(parser_tokval(parser), "case") ||
2209                     !strcmp(parser_tokval(parser), "default"))
2210                 {
2211                     break;
2212                 }
2213             }
2214             if (!parse_statement(parser, caseblock, &expr, true)) {
2215                 ast_delete(switchnode);
2216                 return false;
2217             }
2218             if (!expr)
2219                 continue;
2220             ast_block_add_expr(caseblock, expr);
2221         }
2222     }
2223
2224     /* closing paren */
2225     if (parser->tok != '}') {
2226         ast_delete(switchnode);
2227         parseerror(parser, "expected closing paren of case list");
2228         return false;
2229     }
2230     if (!parser_next(parser)) {
2231         ast_delete(switchnode);
2232         parseerror(parser, "parse error after switch");
2233         return false;
2234     }
2235     *out = (ast_expression*)switchnode;
2236     return true;
2237 }
2238
2239 static bool parse_goto(parser_t *parser, ast_expression **out)
2240 {
2241     size_t    i;
2242     ast_goto *gt;
2243
2244     if (!parser_next(parser) || parser->tok != TOKEN_IDENT) {
2245         parseerror(parser, "expected label name after `goto`");
2246         return false;
2247     }
2248
2249     gt = ast_goto_new(parser_ctx(parser), parser_tokval(parser));
2250
2251     for (i = 0; i < vec_size(parser->labels); ++i) {
2252         if (!strcmp(parser->labels[i]->name, parser_tokval(parser))) {
2253             ast_goto_set_label(gt, parser->labels[i]);
2254             break;
2255         }
2256     }
2257     if (i == vec_size(parser->labels))
2258         vec_push(parser->gotos, gt);
2259
2260     if (!parser_next(parser) || parser->tok != ';') {
2261         parseerror(parser, "semicolon expected after goto label");
2262         return false;
2263     }
2264     if (!parser_next(parser)) {
2265         parseerror(parser, "parse error after goto");
2266         return false;
2267     }
2268
2269     *out = (ast_expression*)gt;
2270     return true;
2271 }
2272
2273 static bool parse_statement(parser_t *parser, ast_block *block, ast_expression **out, bool allow_cases)
2274 {
2275     int cvq;
2276     ast_value *typevar = NULL;
2277     *out = NULL;
2278
2279     if (parser->tok == TOKEN_IDENT)
2280         typevar = parser_find_typedef(parser, parser_tokval(parser), 0);
2281
2282     if (typevar || parser->tok == TOKEN_TYPENAME || parser->tok == '.')
2283     {
2284         /* local variable */
2285         if (!block) {
2286             parseerror(parser, "cannot declare a variable from here");
2287             return false;
2288         }
2289         if (opts_standard == COMPILER_QCC) {
2290             if (parsewarning(parser, WARN_EXTENSIONS, "missing 'local' keyword when declaring a local variable"))
2291                 return false;
2292         }
2293         if (!parse_variable(parser, block, false, CV_NONE, typevar))
2294             return false;
2295         *out = NULL;
2296         return true;
2297     }
2298     else if (parser->tok == TOKEN_IDENT && !strcmp(parser_tokval(parser), "var"))
2299     {
2300         goto ident_var;
2301     }
2302     else if (parser->tok == TOKEN_KEYWORD)
2303     {
2304         if (!strcmp(parser_tokval(parser), "local") ||
2305             !strcmp(parser_tokval(parser), "const") ||
2306             !strcmp(parser_tokval(parser), "var"))
2307         {
2308 ident_var:
2309             if (parser_tokval(parser)[0] == 'c')
2310                 cvq = CV_CONST;
2311             else if (parser_tokval(parser)[0] == 'v')
2312                 cvq = CV_VAR;
2313             else
2314                 cvq = CV_NONE;
2315
2316             if (!block) {
2317                 parseerror(parser, "cannot declare a local variable here");
2318                 return false;
2319             }
2320             if (!parser_next(parser)) {
2321                 parseerror(parser, "expected variable declaration");
2322                 return false;
2323             }
2324             if (!parse_variable(parser, block, true, cvq, NULL))
2325                 return false;
2326             *out = NULL;
2327             return true;
2328         }
2329         else if (!strcmp(parser_tokval(parser), "__builtin_debug_printtype"))
2330         {
2331             char ty[1024];
2332             ast_value *tdef;
2333
2334             if (!parser_next(parser)) {
2335                 parseerror(parser, "parse error after __builtin_debug_printtype");
2336                 return false;
2337             }
2338
2339             if (parser->tok == TOKEN_IDENT && (tdef = parser_find_typedef(parser, parser_tokval(parser), 0)))
2340             {
2341                 ast_type_to_string((ast_expression*)tdef, ty, sizeof(ty));
2342                 con_out("__builtin_debug_printtype: `%s`=`%s`\n", tdef->name, ty);
2343                 if (!parser_next(parser)) {
2344                     parseerror(parser, "parse error after __builtin_debug_printtype typename argument");
2345                     return false;
2346                 }
2347             }
2348             else
2349             {
2350                 if (!parse_statement(parser, block, out, allow_cases))
2351                     return false;
2352                 if (!*out)
2353                     con_out("__builtin_debug_printtype: got no output node\n");
2354                 else
2355                 {
2356                     ast_type_to_string(*out, ty, sizeof(ty));
2357                     con_out("__builtin_debug_printtype: `%s`\n", ty);
2358                 }
2359             }
2360             return true;
2361         }
2362         else if (!strcmp(parser_tokval(parser), "return"))
2363         {
2364             return parse_return(parser, block, out);
2365         }
2366         else if (!strcmp(parser_tokval(parser), "if"))
2367         {
2368             return parse_if(parser, block, out);
2369         }
2370         else if (!strcmp(parser_tokval(parser), "while"))
2371         {
2372             return parse_while(parser, block, out);
2373         }
2374         else if (!strcmp(parser_tokval(parser), "do"))
2375         {
2376             return parse_dowhile(parser, block, out);
2377         }
2378         else if (!strcmp(parser_tokval(parser), "for"))
2379         {
2380             if (opts_standard == COMPILER_QCC) {
2381                 if (parsewarning(parser, WARN_EXTENSIONS, "for loops are not recognized in the original Quake C standard, to enable try an alternate standard --std=?"))
2382                     return false;
2383             }
2384             return parse_for(parser, block, out);
2385         }
2386         else if (!strcmp(parser_tokval(parser), "break"))
2387         {
2388             return parse_break_continue(parser, block, out, false);
2389         }
2390         else if (!strcmp(parser_tokval(parser), "continue"))
2391         {
2392             return parse_break_continue(parser, block, out, true);
2393         }
2394         else if (!strcmp(parser_tokval(parser), "switch"))
2395         {
2396             return parse_switch(parser, block, out);
2397         }
2398         else if (!strcmp(parser_tokval(parser), "case") ||
2399                  !strcmp(parser_tokval(parser), "default"))
2400         {
2401             if (!allow_cases) {
2402                 parseerror(parser, "unexpected 'case' label");
2403                 return false;
2404             }
2405             return true;
2406         }
2407         else if (!strcmp(parser_tokval(parser), "goto"))
2408         {
2409             return parse_goto(parser, out);
2410         }
2411         else if (!strcmp(parser_tokval(parser), "typedef"))
2412         {
2413             if (!parser_next(parser)) {
2414                 parseerror(parser, "expected type definition after 'typedef'");
2415                 return false;
2416             }
2417             return parse_typedef(parser);
2418         }
2419         parseerror(parser, "Unexpected keyword");
2420         return false;
2421     }
2422     else if (parser->tok == '{')
2423     {
2424         ast_block *inner;
2425         inner = parse_block(parser);
2426         if (!inner)
2427             return false;
2428         *out = (ast_expression*)inner;
2429         return true;
2430     }
2431     else if (parser->tok == ':')
2432     {
2433         size_t i;
2434         ast_label *label;
2435         if (!parser_next(parser)) {
2436             parseerror(parser, "expected label name");
2437             return false;
2438         }
2439         if (parser->tok != TOKEN_IDENT) {
2440             parseerror(parser, "label must be an identifier");
2441             return false;
2442         }
2443         label = ast_label_new(parser_ctx(parser), parser_tokval(parser));
2444         if (!label)
2445             return false;
2446         vec_push(parser->labels, label);
2447         *out = (ast_expression*)label;
2448         if (!parser_next(parser)) {
2449             parseerror(parser, "parse error after label");
2450             return false;
2451         }
2452         for (i = 0; i < vec_size(parser->gotos); ++i) {
2453             if (!strcmp(parser->gotos[i]->name, label->name)) {
2454                 ast_goto_set_label(parser->gotos[i], label);
2455                 vec_remove(parser->gotos, i, 1);
2456                 --i;
2457             }
2458         }
2459         return true;
2460     }
2461     else if (parser->tok == ';')
2462     {
2463         if (!parser_next(parser)) {
2464             parseerror(parser, "parse error after empty statement");
2465             return false;
2466         }
2467         return true;
2468     }
2469     else
2470     {
2471         ast_expression *exp = parse_expression(parser, false);
2472         if (!exp)
2473             return false;
2474         *out = exp;
2475         if (!ast_side_effects(exp)) {
2476             if (genwarning(ast_ctx(exp), WARN_EFFECTLESS_STATEMENT, "statement has no effect"))
2477                 return false;
2478         }
2479         return true;
2480     }
2481 }
2482
2483 static bool parse_block_into(parser_t *parser, ast_block *block)
2484 {
2485     bool   retval = true;
2486
2487     parser_enterblock(parser);
2488
2489     if (!parser_next(parser)) { /* skip the '{' */
2490         parseerror(parser, "expected function body");
2491         goto cleanup;
2492     }
2493
2494     while (parser->tok != TOKEN_EOF && parser->tok < TOKEN_ERROR)
2495     {
2496         ast_expression *expr = NULL;
2497         if (parser->tok == '}')
2498             break;
2499
2500         if (!parse_statement(parser, block, &expr, false)) {
2501             /* parseerror(parser, "parse error"); */
2502             block = NULL;
2503             goto cleanup;
2504         }
2505         if (!expr)
2506             continue;
2507         ast_block_add_expr(block, expr);
2508     }
2509
2510     if (parser->tok != '}') {
2511         block = NULL;
2512     } else {
2513         (void)parser_next(parser);
2514     }
2515
2516 cleanup:
2517     if (!parser_leaveblock(parser))
2518         retval = false;
2519     return retval && !!block;
2520 }
2521
2522 static ast_block* parse_block(parser_t *parser)
2523 {
2524     ast_block *block;
2525     block = ast_block_new(parser_ctx(parser));
2526     if (!block)
2527         return NULL;
2528     if (!parse_block_into(parser, block)) {
2529         ast_block_delete(block);
2530         return NULL;
2531     }
2532     return block;
2533 }
2534
2535 static ast_expression* parse_statement_or_block(parser_t *parser)
2536 {
2537     ast_expression *expr = NULL;
2538     if (parser->tok == '{')
2539         return (ast_expression*)parse_block(parser);
2540     if (!parse_statement(parser, NULL, &expr, false))
2541         return NULL;
2542     return expr;
2543 }
2544
2545 static bool create_vector_members(ast_value *var, ast_member **me)
2546 {
2547     size_t i;
2548     size_t len = strlen(var->name);
2549
2550     for (i = 0; i < 3; ++i) {
2551         char *name = mem_a(len+3);
2552         memcpy(name, var->name, len);
2553         name[len+0] = '_';
2554         name[len+1] = 'x'+i;
2555         name[len+2] = 0;
2556         me[i] = ast_member_new(ast_ctx(var), (ast_expression*)var, i, name);
2557         mem_d(name);
2558         if (!me[i])
2559             break;
2560     }
2561     if (i == 3)
2562         return true;
2563
2564     /* unroll */
2565     do { ast_member_delete(me[--i]); } while(i);
2566     return false;
2567 }
2568
2569 static bool parse_function_body(parser_t *parser, ast_value *var)
2570 {
2571     ast_block      *block = NULL;
2572     ast_function   *func;
2573     ast_function   *old;
2574     size_t          parami;
2575
2576     ast_expression *framenum  = NULL;
2577     ast_expression *nextthink = NULL;
2578     /* None of the following have to be deleted */
2579     ast_expression *fld_think = NULL, *fld_nextthink = NULL, *fld_frame = NULL;
2580     ast_expression *gbl_time = NULL, *gbl_self = NULL;
2581     bool            has_frame_think;
2582
2583     bool retval = true;
2584
2585     has_frame_think = false;
2586     old = parser->function;
2587
2588     if (vec_size(parser->gotos) || vec_size(parser->labels)) {
2589         parseerror(parser, "gotos/labels leaking");
2590         return false;
2591     }
2592
2593     if (var->expression.variadic) {
2594         if (parsewarning(parser, WARN_VARIADIC_FUNCTION,
2595                          "variadic function with implementation will not be able to access additional parameters"))
2596         {
2597             return false;
2598         }
2599     }
2600
2601     if (parser->tok == '[') {
2602         /* got a frame definition: [ framenum, nextthink ]
2603          * this translates to:
2604          * self.frame = framenum;
2605          * self.nextthink = time + 0.1;
2606          * self.think = nextthink;
2607          */
2608         nextthink = NULL;
2609
2610         fld_think     = parser_find_field(parser, "think");
2611         fld_nextthink = parser_find_field(parser, "nextthink");
2612         fld_frame     = parser_find_field(parser, "frame");
2613         if (!fld_think || !fld_nextthink || !fld_frame) {
2614             parseerror(parser, "cannot use [frame,think] notation without the required fields");
2615             parseerror(parser, "please declare the following entityfields: `frame`, `think`, `nextthink`");
2616             return false;
2617         }
2618         gbl_time      = parser_find_global(parser, "time");
2619         gbl_self      = parser_find_global(parser, "self");
2620         if (!gbl_time || !gbl_self) {
2621             parseerror(parser, "cannot use [frame,think] notation without the required globals");
2622             parseerror(parser, "please declare the following globals: `time`, `self`");
2623             return false;
2624         }
2625
2626         if (!parser_next(parser))
2627             return false;
2628
2629         framenum = parse_expression_leave(parser, true);
2630         if (!framenum) {
2631             parseerror(parser, "expected a framenumber constant in[frame,think] notation");
2632             return false;
2633         }
2634         if (!ast_istype(framenum, ast_value) || !( (ast_value*)framenum )->hasvalue) {
2635             ast_unref(framenum);
2636             parseerror(parser, "framenumber in [frame,think] notation must be a constant");
2637             return false;
2638         }
2639
2640         if (parser->tok != ',') {
2641             ast_unref(framenum);
2642             parseerror(parser, "expected comma after frame number in [frame,think] notation");
2643             parseerror(parser, "Got a %i\n", parser->tok);
2644             return false;
2645         }
2646
2647         if (!parser_next(parser)) {
2648             ast_unref(framenum);
2649             return false;
2650         }
2651
2652         if (parser->tok == TOKEN_IDENT && !parser_find_var(parser, parser_tokval(parser)))
2653         {
2654             /* qc allows the use of not-yet-declared functions here
2655              * - this automatically creates a prototype */
2656             ast_value      *thinkfunc;
2657             ast_expression *functype = fld_think->expression.next;
2658
2659             thinkfunc = ast_value_new(parser_ctx(parser), parser_tokval(parser), functype->expression.vtype);
2660             if (!thinkfunc || !ast_type_adopt(thinkfunc, functype)) {
2661                 ast_unref(framenum);
2662                 parseerror(parser, "failed to create implicit prototype for `%s`", parser_tokval(parser));
2663                 return false;
2664             }
2665
2666             if (!parser_next(parser)) {
2667                 ast_unref(framenum);
2668                 ast_delete(thinkfunc);
2669                 return false;
2670             }
2671
2672             vec_push(parser->globals, (ast_expression*)thinkfunc);
2673             util_htset(parser->htglobals, thinkfunc->name, thinkfunc);
2674             nextthink = (ast_expression*)thinkfunc;
2675
2676         } else {
2677             nextthink = parse_expression_leave(parser, true);
2678             if (!nextthink) {
2679                 ast_unref(framenum);
2680                 parseerror(parser, "expected a think-function in [frame,think] notation");
2681                 return false;
2682             }
2683         }
2684
2685         if (!ast_istype(nextthink, ast_value)) {
2686             parseerror(parser, "think-function in [frame,think] notation must be a constant");
2687             retval = false;
2688         }
2689
2690         if (retval && parser->tok != ']') {
2691             parseerror(parser, "expected closing `]` for [frame,think] notation");
2692             retval = false;
2693         }
2694
2695         if (retval && !parser_next(parser)) {
2696             retval = false;
2697         }
2698
2699         if (retval && parser->tok != '{') {
2700             parseerror(parser, "a function body has to be declared after a [frame,think] declaration");
2701             retval = false;
2702         }
2703
2704         if (!retval) {
2705             ast_unref(nextthink);
2706             ast_unref(framenum);
2707             return false;
2708         }
2709
2710         has_frame_think = true;
2711     }
2712
2713     block = ast_block_new(parser_ctx(parser));
2714     if (!block) {
2715         parseerror(parser, "failed to allocate block");
2716         if (has_frame_think) {
2717             ast_unref(nextthink);
2718             ast_unref(framenum);
2719         }
2720         return false;
2721     }
2722
2723     if (has_frame_think) {
2724         lex_ctx ctx;
2725         ast_expression *self_frame;
2726         ast_expression *self_nextthink;
2727         ast_expression *self_think;
2728         ast_expression *time_plus_1;
2729         ast_store *store_frame;
2730         ast_store *store_nextthink;
2731         ast_store *store_think;
2732
2733         ctx = parser_ctx(parser);
2734         self_frame     = (ast_expression*)ast_entfield_new(ctx, gbl_self, fld_frame);
2735         self_nextthink = (ast_expression*)ast_entfield_new(ctx, gbl_self, fld_nextthink);
2736         self_think     = (ast_expression*)ast_entfield_new(ctx, gbl_self, fld_think);
2737
2738         time_plus_1    = (ast_expression*)ast_binary_new(ctx, INSTR_ADD_F,
2739                          gbl_time, (ast_expression*)parser_const_float(parser, 0.1));
2740
2741         if (!self_frame || !self_nextthink || !self_think || !time_plus_1) {
2742             if (self_frame)     ast_delete(self_frame);
2743             if (self_nextthink) ast_delete(self_nextthink);
2744             if (self_think)     ast_delete(self_think);
2745             if (time_plus_1)    ast_delete(time_plus_1);
2746             retval = false;
2747         }
2748
2749         if (retval)
2750         {
2751             store_frame     = ast_store_new(ctx, INSTR_STOREP_F,   self_frame,     framenum);
2752             store_nextthink = ast_store_new(ctx, INSTR_STOREP_F,   self_nextthink, time_plus_1);
2753             store_think     = ast_store_new(ctx, INSTR_STOREP_FNC, self_think,     nextthink);
2754
2755             if (!store_frame) {
2756                 ast_delete(self_frame);
2757                 retval = false;
2758             }
2759             if (!store_nextthink) {
2760                 ast_delete(self_nextthink);
2761                 retval = false;
2762             }
2763             if (!store_think) {
2764                 ast_delete(self_think);
2765                 retval = false;
2766             }
2767             if (!retval) {
2768                 if (store_frame)     ast_delete(store_frame);
2769                 if (store_nextthink) ast_delete(store_nextthink);
2770                 if (store_think)     ast_delete(store_think);
2771                 retval = false;
2772             }
2773             ast_block_add_expr(block, (ast_expression*)store_frame);
2774             ast_block_add_expr(block, (ast_expression*)store_nextthink);
2775             ast_block_add_expr(block, (ast_expression*)store_think);
2776         }
2777
2778         if (!retval) {
2779             parseerror(parser, "failed to generate code for [frame,think]");
2780             ast_unref(nextthink);
2781             ast_unref(framenum);
2782             ast_delete(block);
2783             return false;
2784         }
2785     }
2786
2787     parser_enterblock(parser);
2788
2789     for (parami = 0; parami < vec_size(var->expression.params); ++parami) {
2790         size_t     e;
2791         ast_value *param = var->expression.params[parami];
2792         ast_member *me[3];
2793
2794         if (param->expression.vtype != TYPE_VECTOR &&
2795             (param->expression.vtype != TYPE_FIELD ||
2796              param->expression.next->expression.vtype != TYPE_VECTOR))
2797         {
2798             continue;
2799         }
2800
2801         if (!create_vector_members(param, me)) {
2802             ast_block_delete(block);
2803             return false;
2804         }
2805
2806         for (e = 0; e < 3; ++e) {
2807             parser_addlocal(parser, me[e]->name, (ast_expression*)me[e]);
2808             ast_block_collect(block, (ast_expression*)me[e]);
2809         }
2810     }
2811
2812     func = ast_function_new(ast_ctx(var), var->name, var);
2813     if (!func) {
2814         parseerror(parser, "failed to allocate function for `%s`", var->name);
2815         ast_block_delete(block);
2816         goto enderr;
2817     }
2818     vec_push(parser->functions, func);
2819
2820     parser->function = func;
2821     if (!parse_block_into(parser, block)) {
2822         ast_block_delete(block);
2823         goto enderrfn;
2824     }
2825
2826     vec_push(func->blocks, block);
2827
2828     parser->function = old;
2829     if (!parser_leaveblock(parser))
2830         retval = false;
2831     if (vec_size(parser->variables) != PARSER_HT_LOCALS) {
2832         parseerror(parser, "internal error: local scopes left");
2833         retval = false;
2834     }
2835
2836     if (parser->tok == ';')
2837         return parser_next(parser);
2838     else if (opts_standard == COMPILER_QCC)
2839         parseerror(parser, "missing semicolon after function body (mandatory with -std=qcc)");
2840     return retval;
2841
2842 enderrfn:
2843     vec_pop(parser->functions);
2844     ast_function_delete(func);
2845     var->constval.vfunc = NULL;
2846
2847 enderr:
2848     (void)!parser_leaveblock(parser);
2849     parser->function = old;
2850     return false;
2851 }
2852
2853 static ast_expression *array_accessor_split(
2854     parser_t  *parser,
2855     ast_value *array,
2856     ast_value *index,
2857     size_t     middle,
2858     ast_expression *left,
2859     ast_expression *right
2860     )
2861 {
2862     ast_ifthen *ifthen;
2863     ast_binary *cmp;
2864
2865     lex_ctx ctx = ast_ctx(array);
2866
2867     if (!left || !right) {
2868         if (left)  ast_delete(left);
2869         if (right) ast_delete(right);
2870         return NULL;
2871     }
2872
2873     cmp = ast_binary_new(ctx, INSTR_LT,
2874                          (ast_expression*)index,
2875                          (ast_expression*)parser_const_float(parser, middle));
2876     if (!cmp) {
2877         ast_delete(left);
2878         ast_delete(right);
2879         parseerror(parser, "internal error: failed to create comparison for array setter");
2880         return NULL;
2881     }
2882
2883     ifthen = ast_ifthen_new(ctx, (ast_expression*)cmp, left, right);
2884     if (!ifthen) {
2885         ast_delete(cmp); /* will delete left and right */
2886         parseerror(parser, "internal error: failed to create conditional jump for array setter");
2887         return NULL;
2888     }
2889
2890     return (ast_expression*)ifthen;
2891 }
2892
2893 static ast_expression *array_setter_node(parser_t *parser, ast_value *array, ast_value *index, ast_value *value, size_t from, size_t afterend)
2894 {
2895     lex_ctx ctx = ast_ctx(array);
2896
2897     if (from+1 == afterend) {
2898         /* set this value */
2899         ast_block       *block;
2900         ast_return      *ret;
2901         ast_array_index *subscript;
2902         ast_store       *st;
2903         int assignop = type_store_instr[value->expression.vtype];
2904
2905         if (value->expression.vtype == TYPE_FIELD && value->expression.next->expression.vtype == TYPE_VECTOR)
2906             assignop = INSTR_STORE_V;
2907
2908         subscript = ast_array_index_new(ctx, (ast_expression*)array, (ast_expression*)parser_const_float(parser, from));
2909         if (!subscript)
2910             return NULL;
2911
2912         st = ast_store_new(ctx, assignop, (ast_expression*)subscript, (ast_expression*)value);
2913         if (!st) {
2914             ast_delete(subscript);
2915             return NULL;
2916         }
2917
2918         block = ast_block_new(ctx);
2919         if (!block) {
2920             ast_delete(st);
2921             return NULL;
2922         }
2923
2924         ast_block_add_expr(block, (ast_expression*)st);
2925
2926         ret = ast_return_new(ctx, NULL);
2927         if (!ret) {
2928             ast_delete(block);
2929             return NULL;
2930         }
2931
2932         ast_block_add_expr(block, (ast_expression*)ret);
2933
2934         return (ast_expression*)block;
2935     } else {
2936         ast_expression *left, *right;
2937         size_t diff = afterend - from;
2938         size_t middle = from + diff/2;
2939         left  = array_setter_node(parser, array, index, value, from, middle);
2940         right = array_setter_node(parser, array, index, value, middle, afterend);
2941         return array_accessor_split(parser, array, index, middle, left, right);
2942     }
2943 }
2944
2945 static ast_expression *array_field_setter_node(
2946     parser_t  *parser,
2947     ast_value *array,
2948     ast_value *entity,
2949     ast_value *index,
2950     ast_value *value,
2951     size_t     from,
2952     size_t     afterend)
2953 {
2954     lex_ctx ctx = ast_ctx(array);
2955
2956     if (from+1 == afterend) {
2957         /* set this value */
2958         ast_block       *block;
2959         ast_return      *ret;
2960         ast_entfield    *entfield;
2961         ast_array_index *subscript;
2962         ast_store       *st;
2963         int assignop = type_storep_instr[value->expression.vtype];
2964
2965         if (value->expression.vtype == TYPE_FIELD && value->expression.next->expression.vtype == TYPE_VECTOR)
2966             assignop = INSTR_STOREP_V;
2967
2968         subscript = ast_array_index_new(ctx, (ast_expression*)array, (ast_expression*)parser_const_float(parser, from));
2969         if (!subscript)
2970             return NULL;
2971
2972         entfield = ast_entfield_new_force(ctx,
2973                                           (ast_expression*)entity,
2974                                           (ast_expression*)subscript,
2975                                           (ast_expression*)subscript);
2976         if (!entfield) {
2977             ast_delete(subscript);
2978             return NULL;
2979         }
2980
2981         st = ast_store_new(ctx, assignop, (ast_expression*)entfield, (ast_expression*)value);
2982         if (!st) {
2983             ast_delete(entfield);
2984             return NULL;
2985         }
2986
2987         block = ast_block_new(ctx);
2988         if (!block) {
2989             ast_delete(st);
2990             return NULL;
2991         }
2992
2993         ast_block_add_expr(block, (ast_expression*)st);
2994
2995         ret = ast_return_new(ctx, NULL);
2996         if (!ret) {
2997             ast_delete(block);
2998             return NULL;
2999         }
3000
3001         ast_block_add_expr(block, (ast_expression*)ret);
3002
3003         return (ast_expression*)block;
3004     } else {
3005         ast_expression *left, *right;
3006         size_t diff = afterend - from;
3007         size_t middle = from + diff/2;
3008         left  = array_field_setter_node(parser, array, entity, index, value, from, middle);
3009         right = array_field_setter_node(parser, array, entity, index, value, middle, afterend);
3010         return array_accessor_split(parser, array, index, middle, left, right);
3011     }
3012 }
3013
3014 static ast_expression *array_getter_node(parser_t *parser, ast_value *array, ast_value *index, size_t from, size_t afterend)
3015 {
3016     lex_ctx ctx = ast_ctx(array);
3017
3018     if (from+1 == afterend) {
3019         ast_return      *ret;
3020         ast_array_index *subscript;
3021
3022         subscript = ast_array_index_new(ctx, (ast_expression*)array, (ast_expression*)parser_const_float(parser, from));
3023         if (!subscript)
3024             return NULL;
3025
3026         ret = ast_return_new(ctx, (ast_expression*)subscript);
3027         if (!ret) {
3028             ast_delete(subscript);
3029             return NULL;
3030         }
3031
3032         return (ast_expression*)ret;
3033     } else {
3034         ast_expression *left, *right;
3035         size_t diff = afterend - from;
3036         size_t middle = from + diff/2;
3037         left  = array_getter_node(parser, array, index, from, middle);
3038         right = array_getter_node(parser, array, index, middle, afterend);
3039         return array_accessor_split(parser, array, index, middle, left, right);
3040     }
3041 }
3042
3043 static bool parser_create_array_accessor(parser_t *parser, ast_value *array, const char *funcname, ast_value **out)
3044 {
3045     ast_function   *func = NULL;
3046     ast_value      *fval = NULL;
3047     ast_block      *body = NULL;
3048
3049     fval = ast_value_new(ast_ctx(array), funcname, TYPE_FUNCTION);
3050     if (!fval) {
3051         parseerror(parser, "failed to create accessor function value");
3052         return false;
3053     }
3054
3055     func = ast_function_new(ast_ctx(array), funcname, fval);
3056     if (!func) {
3057         ast_delete(fval);
3058         parseerror(parser, "failed to create accessor function node");
3059         return false;
3060     }
3061
3062     body = ast_block_new(ast_ctx(array));
3063     if (!body) {
3064         parseerror(parser, "failed to create block for array accessor");
3065         ast_delete(fval);
3066         ast_delete(func);
3067         return false;
3068     }
3069
3070     vec_push(func->blocks, body);
3071     *out = fval;
3072
3073     vec_push(parser->accessors, fval);
3074
3075     return true;
3076 }
3077
3078 static bool parser_create_array_setter(parser_t *parser, ast_value *array, const char *funcname)
3079 {
3080     ast_expression *root = NULL;
3081     ast_value      *index = NULL;
3082     ast_value      *value = NULL;
3083     ast_function   *func;
3084     ast_value      *fval;
3085
3086     if (!ast_istype(array->expression.next, ast_value)) {
3087         parseerror(parser, "internal error: array accessor needs to build an ast_value with a copy of the element type");
3088         return false;
3089     }
3090
3091     if (!parser_create_array_accessor(parser, array, funcname, &fval))
3092         return false;
3093     func = fval->constval.vfunc;
3094     fval->expression.next = (ast_expression*)ast_value_new(ast_ctx(array), "<void>", TYPE_VOID);
3095
3096     index = ast_value_new(ast_ctx(array), "index", TYPE_FLOAT);
3097     value = ast_value_copy((ast_value*)array->expression.next);
3098
3099     if (!index || !value) {
3100         parseerror(parser, "failed to create locals for array accessor");
3101         goto cleanup;
3102     }
3103     (void)!ast_value_set_name(value, "value"); /* not important */
3104     vec_push(fval->expression.params, index);
3105     vec_push(fval->expression.params, value);
3106
3107     root = array_setter_node(parser, array, index, value, 0, array->expression.count);
3108     if (!root) {
3109         parseerror(parser, "failed to build accessor search tree");
3110         goto cleanup;
3111     }
3112
3113     ast_block_add_expr(func->blocks[0], root);
3114     array->setter = fval;
3115     return true;
3116 cleanup:
3117     if (index) ast_delete(index);
3118     if (value) ast_delete(value);
3119     if (root)  ast_delete(root);
3120     ast_delete(func);
3121     ast_delete(fval);
3122     return false;
3123 }
3124
3125 static bool parser_create_array_field_setter(parser_t *parser, ast_value *array, const char *funcname)
3126 {
3127     ast_expression *root = NULL;
3128     ast_value      *entity = NULL;
3129     ast_value      *index = NULL;
3130     ast_value      *value = NULL;
3131     ast_function   *func;
3132     ast_value      *fval;
3133
3134     if (!ast_istype(array->expression.next, ast_value)) {
3135         parseerror(parser, "internal error: array accessor needs to build an ast_value with a copy of the element type");
3136         return false;
3137     }
3138
3139     if (!parser_create_array_accessor(parser, array, funcname, &fval))
3140         return false;
3141     func = fval->constval.vfunc;
3142     fval->expression.next = (ast_expression*)ast_value_new(ast_ctx(array), "<void>", TYPE_VOID);
3143
3144     entity = ast_value_new(ast_ctx(array), "entity", TYPE_ENTITY);
3145     index  = ast_value_new(ast_ctx(array), "index",  TYPE_FLOAT);
3146     value  = ast_value_copy((ast_value*)array->expression.next);
3147     if (!entity || !index || !value) {
3148         parseerror(parser, "failed to create locals for array accessor");
3149         goto cleanup;
3150     }
3151     (void)!ast_value_set_name(value, "value"); /* not important */
3152     vec_push(fval->expression.params, entity);
3153     vec_push(fval->expression.params, index);
3154     vec_push(fval->expression.params, value);
3155
3156     root = array_field_setter_node(parser, array, entity, index, value, 0, array->expression.count);
3157     if (!root) {
3158         parseerror(parser, "failed to build accessor search tree");
3159         goto cleanup;
3160     }
3161
3162     ast_block_add_expr(func->blocks[0], root);
3163     array->setter = fval;
3164     return true;
3165 cleanup:
3166     if (entity) ast_delete(entity);
3167     if (index)  ast_delete(index);
3168     if (value)  ast_delete(value);
3169     if (root)   ast_delete(root);
3170     ast_delete(func);
3171     ast_delete(fval);
3172     return false;
3173 }
3174
3175 static bool parser_create_array_getter(parser_t *parser, ast_value *array, const ast_expression *elemtype, const char *funcname)
3176 {
3177     ast_expression *root = NULL;
3178     ast_value      *index = NULL;
3179     ast_value      *fval;
3180     ast_function   *func;
3181
3182     /* NOTE: checking array->expression.next rather than elemtype since
3183      * for fields elemtype is a temporary fieldtype.
3184      */
3185     if (!ast_istype(array->expression.next, ast_value)) {
3186         parseerror(parser, "internal error: array accessor needs to build an ast_value with a copy of the element type");
3187         return false;
3188     }
3189
3190     if (!parser_create_array_accessor(parser, array, funcname, &fval))
3191         return false;
3192     func = fval->constval.vfunc;
3193     fval->expression.next = ast_type_copy(ast_ctx(array), elemtype);
3194
3195     index = ast_value_new(ast_ctx(array), "index", TYPE_FLOAT);
3196
3197     if (!index) {
3198         parseerror(parser, "failed to create locals for array accessor");
3199         goto cleanup;
3200     }
3201     vec_push(fval->expression.params, index);
3202
3203     root = array_getter_node(parser, array, index, 0, array->expression.count);
3204     if (!root) {
3205         parseerror(parser, "failed to build accessor search tree");
3206         goto cleanup;
3207     }
3208
3209     ast_block_add_expr(func->blocks[0], root);
3210     array->getter = fval;
3211     return true;
3212 cleanup:
3213     if (index) ast_delete(index);
3214     if (root)  ast_delete(root);
3215     ast_delete(func);
3216     ast_delete(fval);
3217     return false;
3218 }
3219
3220 static ast_value *parse_typename(parser_t *parser, ast_value **storebase, ast_value *cached_typedef);
3221 static ast_value *parse_parameter_list(parser_t *parser, ast_value *var)
3222 {
3223     lex_ctx     ctx;
3224     size_t      i;
3225     ast_value **params;
3226     ast_value  *param;
3227     ast_value  *fval;
3228     bool        first = true;
3229     bool        variadic = false;
3230
3231     ctx = parser_ctx(parser);
3232
3233     /* for the sake of less code we parse-in in this function */
3234     if (!parser_next(parser)) {
3235         parseerror(parser, "expected parameter list");
3236         return NULL;
3237     }
3238
3239     params = NULL;
3240
3241     /* parse variables until we hit a closing paren */
3242     while (parser->tok != ')') {
3243         if (!first) {
3244             /* there must be commas between them */
3245             if (parser->tok != ',') {
3246                 parseerror(parser, "expected comma or end of parameter list");
3247                 goto on_error;
3248             }
3249             if (!parser_next(parser)) {
3250                 parseerror(parser, "expected parameter");
3251                 goto on_error;
3252             }
3253         }
3254         first = false;
3255
3256         if (parser->tok == TOKEN_DOTS) {
3257             /* '...' indicates a varargs function */
3258             variadic = true;
3259             if (!parser_next(parser)) {
3260                 parseerror(parser, "expected parameter");
3261                 return NULL;
3262             }
3263             if (parser->tok != ')') {
3264                 parseerror(parser, "`...` must be the last parameter of a variadic function declaration");
3265                 goto on_error;
3266             }
3267         }
3268         else
3269         {
3270             /* for anything else just parse a typename */
3271             param = parse_typename(parser, NULL, NULL);
3272             if (!param)
3273                 goto on_error;
3274             vec_push(params, param);
3275             if (param->expression.vtype >= TYPE_VARIANT) {
3276                 char typename[1024];
3277                 ast_type_to_string((ast_expression*)param, typename, sizeof(typename));
3278                 parseerror(parser, "type not supported as part of a parameter list: %s", typename);
3279                 goto on_error;
3280             }
3281         }
3282     }
3283
3284     if (vec_size(params) == 1 && params[0]->expression.vtype == TYPE_VOID)
3285         vec_free(params);
3286
3287     /* sanity check */
3288     if (vec_size(params) > 8 && opts_standard == COMPILER_QCC)
3289         (void)!parsewarning(parser, WARN_EXTENSIONS, "more than 8 parameters are not supported by this standard");
3290
3291     /* parse-out */
3292     if (!parser_next(parser)) {
3293         parseerror(parser, "parse error after typename");
3294         goto on_error;
3295     }
3296
3297     /* now turn 'var' into a function type */
3298     fval = ast_value_new(ctx, "<type()>", TYPE_FUNCTION);
3299     fval->expression.next     = (ast_expression*)var;
3300     fval->expression.variadic = variadic;
3301     var = fval;
3302
3303     var->expression.params = params;
3304     params = NULL;
3305
3306     return var;
3307
3308 on_error:
3309     ast_delete(var);
3310     for (i = 0; i < vec_size(params); ++i)
3311         ast_delete(params[i]);
3312     vec_free(params);
3313     return NULL;
3314 }
3315
3316 static ast_value *parse_arraysize(parser_t *parser, ast_value *var)
3317 {
3318     ast_expression *cexp;
3319     ast_value      *cval, *tmp;
3320     lex_ctx ctx;
3321
3322     ctx = parser_ctx(parser);
3323
3324     if (!parser_next(parser)) {
3325         ast_delete(var);
3326         parseerror(parser, "expected array-size");
3327         return NULL;
3328     }
3329
3330     cexp = parse_expression_leave(parser, true);
3331
3332     if (!cexp || !ast_istype(cexp, ast_value)) {
3333         if (cexp)
3334             ast_unref(cexp);
3335         ast_delete(var);
3336         parseerror(parser, "expected array-size as constant positive integer");
3337         return NULL;
3338     }
3339     cval = (ast_value*)cexp;
3340
3341     tmp = ast_value_new(ctx, "<type[]>", TYPE_ARRAY);
3342     tmp->expression.next = (ast_expression*)var;
3343     var = tmp;
3344
3345     if (cval->expression.vtype == TYPE_INTEGER)
3346         tmp->expression.count = cval->constval.vint;
3347     else if (cval->expression.vtype == TYPE_FLOAT)
3348         tmp->expression.count = cval->constval.vfloat;
3349     else {
3350         ast_unref(cexp);
3351         ast_delete(var);
3352         parseerror(parser, "array-size must be a positive integer constant");
3353         return NULL;
3354     }
3355     ast_unref(cexp);
3356
3357     if (parser->tok != ']') {
3358         ast_delete(var);
3359         parseerror(parser, "expected ']' after array-size");
3360         return NULL;
3361     }
3362     if (!parser_next(parser)) {
3363         ast_delete(var);
3364         parseerror(parser, "error after parsing array size");
3365         return NULL;
3366     }
3367     return var;
3368 }
3369
3370 /* Parse a complete typename.
3371  * for single-variables (ie. function parameters or typedefs) storebase should be NULL
3372  * but when parsing variables separated by comma
3373  * 'storebase' should point to where the base-type should be kept.
3374  * The base type makes up every bit of type information which comes *before* the
3375  * variable name.
3376  *
3377  * The following will be parsed in its entirety:
3378  *     void() foo()
3379  * The 'basetype' in this case is 'void()'
3380  * and if there's a comma after it, say:
3381  *     void() foo(), bar
3382  * then the type-information 'void()' can be stored in 'storebase'
3383  */
3384 static ast_value *parse_typename(parser_t *parser, ast_value **storebase, ast_value *cached_typedef)
3385 {
3386     ast_value *var, *tmp;
3387     lex_ctx    ctx;
3388
3389     const char *name = NULL;
3390     bool        isfield  = false;
3391     bool        wasarray = false;
3392     size_t      morefields = 0;
3393
3394     ctx = parser_ctx(parser);
3395
3396     /* types may start with a dot */
3397     if (parser->tok == '.') {
3398         isfield = true;
3399         /* if we parsed a dot we need a typename now */
3400         if (!parser_next(parser)) {
3401             parseerror(parser, "expected typename for field definition");
3402             return NULL;
3403         }
3404
3405         /* Further dots are handled seperately because they won't be part of the
3406          * basetype
3407          */
3408         while (parser->tok == '.') {
3409             ++morefields;
3410             if (!parser_next(parser)) {
3411                 parseerror(parser, "expected typename for field definition");
3412                 return NULL;
3413             }
3414         }
3415     }
3416     if (parser->tok == TOKEN_IDENT)
3417         cached_typedef = parser_find_typedef(parser, parser_tokval(parser), 0);
3418     if (!cached_typedef && parser->tok != TOKEN_TYPENAME) {
3419         parseerror(parser, "expected typename");
3420         return NULL;
3421     }
3422
3423     /* generate the basic type value */
3424     if (cached_typedef) {
3425         var = ast_value_copy(cached_typedef);
3426         ast_value_set_name(var, "<type(from_def)>");
3427     } else
3428         var = ast_value_new(ctx, "<type>", parser_token(parser)->constval.t);
3429
3430     for (; morefields; --morefields) {
3431         tmp = ast_value_new(ctx, "<.type>", TYPE_FIELD);
3432         tmp->expression.next = (ast_expression*)var;
3433         var = tmp;
3434     }
3435
3436     /* do not yet turn into a field - remember:
3437      * .void() foo; is a field too
3438      * .void()() foo; is a function
3439      */
3440
3441     /* parse on */
3442     if (!parser_next(parser)) {
3443         ast_delete(var);
3444         parseerror(parser, "parse error after typename");
3445         return NULL;
3446     }
3447
3448     /* an opening paren now starts the parameter-list of a function
3449      * this is where original-QC has parameter lists.
3450      * We allow a single parameter list here.
3451      * Much like fteqcc we don't allow `float()() x`
3452      */
3453     if (parser->tok == '(') {
3454         var = parse_parameter_list(parser, var);
3455         if (!var)
3456             return NULL;
3457     }
3458
3459     /* store the base if requested */
3460     if (storebase) {
3461         *storebase = ast_value_copy(var);
3462         if (isfield) {
3463             tmp = ast_value_new(ctx, "<type:f>", TYPE_FIELD);
3464             tmp->expression.next = (ast_expression*)*storebase;
3465             *storebase = tmp;
3466         }
3467     }
3468
3469     /* there may be a name now */
3470     if (parser->tok == TOKEN_IDENT) {
3471         name = util_strdup(parser_tokval(parser));
3472         /* parse on */
3473         if (!parser_next(parser)) {
3474             ast_delete(var);
3475             parseerror(parser, "error after variable or field declaration");
3476             return NULL;
3477         }
3478     }
3479
3480     /* now this may be an array */
3481     if (parser->tok == '[') {
3482         wasarray = true;
3483         var = parse_arraysize(parser, var);
3484         if (!var)
3485             return NULL;
3486     }
3487
3488     /* This is the point where we can turn it into a field */
3489     if (isfield) {
3490         /* turn it into a field if desired */
3491         tmp = ast_value_new(ctx, "<type:f>", TYPE_FIELD);
3492         tmp->expression.next = (ast_expression*)var;
3493         var = tmp;
3494     }
3495
3496     /* now there may be function parens again */
3497     if (parser->tok == '(' && opts_standard == COMPILER_QCC)
3498         parseerror(parser, "C-style function syntax is not allowed in -std=qcc");
3499     if (parser->tok == '(' && wasarray)
3500         parseerror(parser, "arrays as part of a return type is not supported");
3501     while (parser->tok == '(') {
3502         var = parse_parameter_list(parser, var);
3503         if (!var) {
3504             if (name)
3505                 mem_d((void*)name);
3506             ast_delete(var);
3507             return NULL;
3508         }
3509     }
3510
3511     /* finally name it */
3512     if (name) {
3513         if (!ast_value_set_name(var, name)) {
3514             ast_delete(var);
3515             parseerror(parser, "internal error: failed to set name");
3516             return NULL;
3517         }
3518         /* free the name, ast_value_set_name duplicates */
3519         mem_d((void*)name);
3520     }
3521
3522     return var;
3523 }
3524
3525 static bool parse_typedef(parser_t *parser)
3526 {
3527     ast_value      *typevar, *oldtype;
3528     ast_expression *old;
3529
3530     typevar = parse_typename(parser, NULL, NULL);
3531
3532     if (!typevar)
3533         return false;
3534
3535     if ( (old = parser_find_var(parser, typevar->name)) ) {
3536         parseerror(parser, "cannot define a type with the same name as a variable: %s\n"
3537                    " -> `%s` has been declared here: %s:%i",
3538                    typevar->name, ast_ctx(old).file, ast_ctx(old).line);
3539         ast_delete(typevar);
3540         return false;
3541     }
3542
3543     if ( (oldtype = parser_find_typedef(parser, typevar->name, vec_last(parser->_blocktypedefs))) ) {
3544         parseerror(parser, "type `%s` has already been declared here: %s:%i",
3545                    typevar->name, ast_ctx(oldtype).file, ast_ctx(oldtype).line);
3546         ast_delete(typevar);
3547         return false;
3548     }
3549
3550     vec_push(parser->_typedefs, typevar);
3551     util_htset(vec_last(parser->typedefs), typevar->name, typevar);
3552
3553     if (parser->tok != ';') {
3554         parseerror(parser, "expected semicolon after typedef");
3555         return false;
3556     }
3557     if (!parser_next(parser)) {
3558         parseerror(parser, "parse error after typedef");
3559         return false;
3560     }
3561
3562     return true;
3563 }
3564
3565 static bool parse_variable(parser_t *parser, ast_block *localblock, bool nofields, int is_const_var, ast_value *cached_typedef)
3566 {
3567     ast_value *var;
3568     ast_value *proto;
3569     ast_expression *old;
3570     bool       was_end;
3571     size_t     i;
3572
3573     ast_value *basetype = NULL;
3574     bool      retval    = true;
3575     bool      isparam   = false;
3576     bool      isvector  = false;
3577     bool      cleanvar  = true;
3578     bool      wasarray  = false;
3579
3580     ast_member *me[3];
3581
3582     /* get the first complete variable */
3583     var = parse_typename(parser, &basetype, cached_typedef);
3584     if (!var) {
3585         if (basetype)
3586             ast_delete(basetype);
3587         return false;
3588     }
3589
3590     while (true) {
3591         proto = NULL;
3592         wasarray = false;
3593
3594         /* Part 0: finish the type */
3595         if (parser->tok == '(') {
3596             if (opts_standard == COMPILER_QCC)
3597                 parseerror(parser, "C-style function syntax is not allowed in -std=qcc");
3598             var = parse_parameter_list(parser, var);
3599             if (!var) {
3600                 retval = false;
3601                 goto cleanup;
3602             }
3603         }
3604         /* we only allow 1-dimensional arrays */
3605         if (parser->tok == '[') {
3606             wasarray = true;
3607             var = parse_arraysize(parser, var);
3608             if (!var) {
3609                 retval = false;
3610                 goto cleanup;
3611             }
3612         }
3613         if (parser->tok == '(' && wasarray) {
3614             parseerror(parser, "arrays as part of a return type is not supported");
3615             /* we'll still parse the type completely for now */
3616         }
3617         /* for functions returning functions */
3618         while (parser->tok == '(') {
3619             if (opts_standard == COMPILER_QCC)
3620                 parseerror(parser, "C-style function syntax is not allowed in -std=qcc");
3621             var = parse_parameter_list(parser, var);
3622             if (!var) {
3623                 retval = false;
3624                 goto cleanup;
3625             }
3626         }
3627
3628         if (is_const_var == CV_CONST)
3629             var->cvq = CV_CONST;
3630
3631         /* Part 1:
3632          * check for validity: (end_sys_..., multiple-definitions, prototypes, ...)
3633          * Also: if there was a prototype, `var` will be deleted and set to `proto` which
3634          * is then filled with the previous definition and the parameter-names replaced.
3635          */
3636         if (!localblock) {
3637             /* Deal with end_sys_ vars */
3638             was_end = false;
3639             if (!strcmp(var->name, "end_sys_globals")) {
3640                 parser->crc_globals = vec_size(parser->globals);
3641                 was_end = true;
3642             }
3643             else if (!strcmp(var->name, "end_sys_fields")) {
3644                 parser->crc_fields = vec_size(parser->fields);
3645                 was_end = true;
3646             }
3647             if (was_end && var->expression.vtype == TYPE_FIELD) {
3648                 if (parsewarning(parser, WARN_END_SYS_FIELDS,
3649                                  "global '%s' hint should not be a field",
3650                                  parser_tokval(parser)))
3651                 {
3652                     retval = false;
3653                     goto cleanup;
3654                 }
3655             }
3656
3657             if (!nofields && var->expression.vtype == TYPE_FIELD)
3658             {
3659                 /* deal with field declarations */
3660                 old = parser_find_field(parser, var->name);
3661                 if (old) {
3662                     if (parsewarning(parser, WARN_FIELD_REDECLARED, "field `%s` already declared here: %s:%i",
3663                                      var->name, ast_ctx(old).file, (int)ast_ctx(old).line))
3664                     {
3665                         retval = false;
3666                         goto cleanup;
3667                     }
3668                     ast_delete(var);
3669                     var = NULL;
3670                     goto skipvar;
3671                     /*
3672                     parseerror(parser, "field `%s` already declared here: %s:%i",
3673                                var->name, ast_ctx(old).file, ast_ctx(old).line);
3674                     retval = false;
3675                     goto cleanup;
3676                     */
3677                 }
3678                 if (opts_standard == COMPILER_QCC &&
3679                     (old = parser_find_global(parser, var->name)))
3680                 {
3681                     parseerror(parser, "cannot declare a field and a global of the same name with -std=qcc");
3682                     parseerror(parser, "field `%s` already declared here: %s:%i",
3683                                var->name, ast_ctx(old).file, ast_ctx(old).line);
3684                     retval = false;
3685                     goto cleanup;
3686                 }
3687             }
3688             else
3689             {
3690                 /* deal with other globals */
3691                 old = parser_find_global(parser, var->name);
3692                 if (old && var->expression.vtype == TYPE_FUNCTION && old->expression.vtype == TYPE_FUNCTION)
3693                 {
3694                     /* This is a function which had a prototype */
3695                     if (!ast_istype(old, ast_value)) {
3696                         parseerror(parser, "internal error: prototype is not an ast_value");
3697                         retval = false;
3698                         goto cleanup;
3699                     }
3700                     proto = (ast_value*)old;
3701                     if (!ast_compare_type((ast_expression*)proto, (ast_expression*)var)) {
3702                         parseerror(parser, "conflicting types for `%s`, previous declaration was here: %s:%i",
3703                                    proto->name,
3704                                    ast_ctx(proto).file, ast_ctx(proto).line);
3705                         retval = false;
3706                         goto cleanup;
3707                     }
3708                     /* we need the new parameter-names */
3709                     for (i = 0; i < vec_size(proto->expression.params); ++i)
3710                         ast_value_set_name(proto->expression.params[i], var->expression.params[i]->name);
3711                     ast_delete(var);
3712                     var = proto;
3713                 }
3714                 else
3715                 {
3716                     /* other globals */
3717                     if (old) {
3718                         if (opts_standard == COMPILER_GMQCC) {
3719                             parseerror(parser, "global `%s` already declared here: %s:%i",
3720                                        var->name, ast_ctx(old).file, ast_ctx(old).line);
3721                             retval = false;
3722                             goto cleanup;
3723                         } else {
3724                             if (parsewarning(parser, WARN_DOUBLE_DECLARATION,
3725                                              "global `%s` already declared here: %s:%i",
3726                                              var->name, ast_ctx(old).file, ast_ctx(old).line))
3727                             {
3728                                 retval = false;
3729                                 goto cleanup;
3730                             }
3731                             proto = (ast_value*)old;
3732                             if (!ast_istype(old, ast_value)) {
3733                                 parseerror(parser, "internal error: not an ast_value");
3734                                 retval = false;
3735                                 proto = NULL;
3736                                 goto cleanup;
3737                             }
3738                             ast_delete(var);
3739                             var = proto;
3740                         }
3741                     }
3742                     if (opts_standard == COMPILER_QCC &&
3743                         (old = parser_find_field(parser, var->name)))
3744                     {
3745                         parseerror(parser, "cannot declare a field and a global of the same name with -std=qcc");
3746                         parseerror(parser, "global `%s` already declared here: %s:%i",
3747                                    var->name, ast_ctx(old).file, ast_ctx(old).line);
3748                         retval = false;
3749                         goto cleanup;
3750                     }
3751                 }
3752             }
3753         }
3754         else /* it's not a global */
3755         {
3756             old = parser_find_local(parser, var->name, vec_size(parser->variables)-1, &isparam);
3757             if (old && !isparam) {
3758                 parseerror(parser, "local `%s` already declared here: %s:%i",
3759                            var->name, ast_ctx(old).file, (int)ast_ctx(old).line);
3760                 retval = false;
3761                 goto cleanup;
3762             }
3763             old = parser_find_local(parser, var->name, 0, &isparam);
3764             if (old && isparam) {
3765                 if (parsewarning(parser, WARN_LOCAL_SHADOWS,
3766                                  "local `%s` is shadowing a parameter", var->name))
3767                 {
3768                     parseerror(parser, "local `%s` already declared here: %s:%i",
3769                                var->name, ast_ctx(old).file, (int)ast_ctx(old).line);
3770                     retval = false;
3771                     goto cleanup;
3772                 }
3773                 if (opts_standard != COMPILER_GMQCC) {
3774                     ast_delete(var);
3775                     var = NULL;
3776                     goto skipvar;
3777                 }
3778             }
3779         }
3780
3781         /* Part 2:
3782          * Create the global/local, and deal with vector types.
3783          */
3784         if (!proto) {
3785             if (var->expression.vtype == TYPE_VECTOR)
3786                 isvector = true;
3787             else if (var->expression.vtype == TYPE_FIELD &&
3788                      var->expression.next->expression.vtype == TYPE_VECTOR)
3789                 isvector = true;
3790
3791             if (isvector) {
3792                 if (!create_vector_members(var, me)) {
3793                     retval = false;
3794                     goto cleanup;
3795                 }
3796             }
3797
3798             if (!localblock) {
3799                 /* deal with global variables, fields, functions */
3800                 if (!nofields && var->expression.vtype == TYPE_FIELD) {
3801                     vec_push(parser->fields, (ast_expression*)var);
3802                     util_htset(parser->htfields, var->name, var);
3803                     if (isvector) {
3804                         for (i = 0; i < 3; ++i) {
3805                             vec_push(parser->fields, (ast_expression*)me[i]);
3806                             util_htset(parser->htfields, me[i]->name, me[i]);
3807                         }
3808                     }
3809                 }
3810                 else {
3811                     vec_push(parser->globals, (ast_expression*)var);
3812                     util_htset(parser->htglobals, var->name, var);
3813                     if (isvector) {
3814                         for (i = 0; i < 3; ++i) {
3815                             vec_push(parser->globals, (ast_expression*)me[i]);
3816                             util_htset(parser->htglobals, me[i]->name, me[i]);
3817                         }
3818                     }
3819                 }
3820             } else {
3821                 vec_push(localblock->locals, var);
3822                 parser_addlocal(parser, var->name, (ast_expression*)var);
3823                 if (isvector) {
3824                     for (i = 0; i < 3; ++i) {
3825                         parser_addlocal(parser, me[i]->name, (ast_expression*)me[i]);
3826                         ast_block_collect(localblock, (ast_expression*)me[i]);
3827                     }
3828                 }
3829             }
3830
3831         }
3832         me[0] = me[1] = me[2] = NULL;
3833         cleanvar = false;
3834         /* Part 2.2
3835          * deal with arrays
3836          */
3837         if (var->expression.vtype == TYPE_ARRAY) {
3838             char name[1024];
3839             snprintf(name, sizeof(name), "%s##SET", var->name);
3840             if (!parser_create_array_setter(parser, var, name))
3841                 goto cleanup;
3842             snprintf(name, sizeof(name), "%s##GET", var->name);
3843             if (!parser_create_array_getter(parser, var, var->expression.next, name))
3844                 goto cleanup;
3845         }
3846         else if (!localblock && !nofields &&
3847                  var->expression.vtype == TYPE_FIELD &&
3848                  var->expression.next->expression.vtype == TYPE_ARRAY)
3849         {
3850             char name[1024];
3851             ast_expression *telem;
3852             ast_value      *tfield;
3853             ast_value      *array = (ast_value*)var->expression.next;
3854
3855             if (!ast_istype(var->expression.next, ast_value)) {
3856                 parseerror(parser, "internal error: field element type must be an ast_value");
3857                 goto cleanup;
3858             }
3859
3860             snprintf(name, sizeof(name), "%s##SETF", var->name);
3861             if (!parser_create_array_field_setter(parser, array, name))
3862                 goto cleanup;
3863
3864             telem = ast_type_copy(ast_ctx(var), array->expression.next);
3865             tfield = ast_value_new(ast_ctx(var), "<.type>", TYPE_FIELD);
3866             tfield->expression.next = telem;
3867             snprintf(name, sizeof(name), "%s##GETFP", var->name);
3868             if (!parser_create_array_getter(parser, array, (ast_expression*)tfield, name)) {
3869                 ast_delete(tfield);
3870                 goto cleanup;
3871             }
3872             ast_delete(tfield);
3873         }
3874
3875 skipvar:
3876         if (parser->tok == ';') {
3877             ast_delete(basetype);
3878             if (!parser_next(parser)) {
3879                 parseerror(parser, "error after variable declaration");
3880                 return false;
3881             }
3882             return true;
3883         }
3884
3885         if (parser->tok == ',')
3886             goto another;
3887
3888         if (!var || (!localblock && !nofields && basetype->expression.vtype == TYPE_FIELD)) {
3889             parseerror(parser, "missing comma or semicolon while parsing variables");
3890             break;
3891         }
3892
3893         if (localblock && opts_standard == COMPILER_QCC) {
3894             if (parsewarning(parser, WARN_LOCAL_CONSTANTS,
3895                              "initializing expression turns variable `%s` into a constant in this standard",
3896                              var->name) )
3897             {
3898                 break;
3899             }
3900         }
3901
3902         if (parser->tok != '{') {
3903             if (parser->tok != '=') {
3904                 parseerror(parser, "missing semicolon or initializer, got: `%s`", parser_tokval(parser));
3905                 break;
3906             }
3907
3908             if (!parser_next(parser)) {
3909                 parseerror(parser, "error parsing initializer");
3910                 break;
3911             }
3912         }
3913         else if (opts_standard == COMPILER_QCC) {
3914             parseerror(parser, "expected '=' before function body in this standard");
3915         }
3916
3917         if (parser->tok == '#') {
3918             ast_function *func = NULL;
3919
3920             if (localblock) {
3921                 parseerror(parser, "cannot declare builtins within functions");
3922                 break;
3923             }
3924             if (var->expression.vtype != TYPE_FUNCTION) {
3925                 parseerror(parser, "unexpected builtin number, '%s' is not a function", var->name);
3926                 break;
3927             }
3928             if (!parser_next(parser)) {
3929                 parseerror(parser, "expected builtin number");
3930                 break;
3931             }
3932             if (parser->tok != TOKEN_INTCONST) {
3933                 parseerror(parser, "builtin number must be an integer constant");
3934                 break;
3935             }
3936             if (parser_token(parser)->constval.i <= 0) {
3937                 parseerror(parser, "builtin number must be an integer greater than zero");
3938                 break;
3939             }
3940
3941             if (var->hasvalue) {
3942                 (void)!parsewarning(parser, WARN_DOUBLE_DECLARATION,
3943                                     "builtin `%s` has already been defined\n"
3944                                     " -> previous declaration here: %s:%i",
3945                                     var->name, ast_ctx(var).file, (int)ast_ctx(var).line);
3946             }
3947             else
3948             {
3949                 func = ast_function_new(ast_ctx(var), var->name, var);
3950                 if (!func) {
3951                     parseerror(parser, "failed to allocate function for `%s`", var->name);
3952                     break;
3953                 }
3954                 vec_push(parser->functions, func);
3955
3956                 func->builtin = -parser_token(parser)->constval.i;
3957             }
3958
3959             if (!parser_next(parser)) {
3960                 parseerror(parser, "expected comma or semicolon");
3961                 if (func)
3962                     ast_function_delete(func);
3963                 var->constval.vfunc = NULL;
3964                 break;
3965             }
3966         }
3967         else if (parser->tok == '{' || parser->tok == '[')
3968         {
3969             size_t i;
3970             if (localblock) {
3971                 parseerror(parser, "cannot declare functions within functions");
3972                 break;
3973             }
3974
3975             if (proto)
3976                 ast_ctx(proto) = parser_ctx(parser);
3977
3978             if (!parse_function_body(parser, var))
3979                 break;
3980             ast_delete(basetype);
3981             for (i = 0; i < vec_size(parser->gotos); ++i)
3982                 parseerror(parser, "undefined label: `%s`", parser->gotos[i]->name);
3983             vec_free(parser->gotos);
3984             vec_free(parser->labels);
3985             return true;
3986         } else {
3987             ast_expression *cexp;
3988             ast_value      *cval;
3989
3990             cexp = parse_expression_leave(parser, true);
3991             if (!cexp)
3992                 break;
3993
3994             if (!localblock) {
3995                 cval = (ast_value*)cexp;
3996                 if (!ast_istype(cval, ast_value) || !cval->hasvalue || cval->cvq != CV_CONST)
3997                     parseerror(parser, "cannot initialize a global constant variable with a non-constant expression");
3998                 else
3999                 {
4000                     if (opts_standard != COMPILER_GMQCC &&
4001                         !OPTS_FLAG(INITIALIZED_NONCONSTANTS) &&
4002                         is_const_var != CV_VAR)
4003                     {
4004                         var->cvq = CV_CONST;
4005                     }
4006                     var->hasvalue = true;
4007                     if (cval->expression.vtype == TYPE_STRING)
4008                         var->constval.vstring = parser_strdup(cval->constval.vstring);
4009                     else
4010                         memcpy(&var->constval, &cval->constval, sizeof(var->constval));
4011                     ast_unref(cval);
4012                 }
4013             } else {
4014                 bool cvq;
4015                 shunt sy = { NULL, NULL };
4016                 cvq = var->cvq;
4017                 var->cvq = CV_NONE;
4018                 vec_push(sy.out, syexp(ast_ctx(var), (ast_expression*)var));
4019                 vec_push(sy.out, syexp(ast_ctx(cexp), (ast_expression*)cexp));
4020                 vec_push(sy.ops, syop(ast_ctx(var), parser->assign_op));
4021                 if (!parser_sy_pop(parser, &sy))
4022                     ast_unref(cexp);
4023                 else {
4024                     if (vec_size(sy.out) != 1 && vec_size(sy.ops) != 0)
4025                         parseerror(parser, "internal error: leaked operands");
4026                     ast_block_add_expr(localblock, (ast_expression*)sy.out[0].out);
4027                 }
4028                 vec_free(sy.out);
4029                 vec_free(sy.ops);
4030                 var->cvq = cvq;
4031             }
4032         }
4033
4034 another:
4035         if (parser->tok == ',') {
4036             if (!parser_next(parser)) {
4037                 parseerror(parser, "expected another variable");
4038                 break;
4039             }
4040
4041             if (parser->tok != TOKEN_IDENT) {
4042                 parseerror(parser, "expected another variable");
4043                 break;
4044             }
4045             var = ast_value_copy(basetype);
4046             cleanvar = true;
4047             ast_value_set_name(var, parser_tokval(parser));
4048             if (!parser_next(parser)) {
4049                 parseerror(parser, "error parsing variable declaration");
4050                 break;
4051             }
4052             continue;
4053         }
4054
4055         if (parser->tok != ';') {
4056             parseerror(parser, "missing semicolon after variables");
4057             break;
4058         }
4059
4060         if (!parser_next(parser)) {
4061             parseerror(parser, "parse error after variable declaration");
4062             break;
4063         }
4064
4065         ast_delete(basetype);
4066         return true;
4067     }
4068
4069     if (cleanvar && var)
4070         ast_delete(var);
4071     ast_delete(basetype);
4072     return false;
4073
4074 cleanup:
4075     ast_delete(basetype);
4076     if (cleanvar && var)
4077         ast_delete(var);
4078     if (me[0]) ast_member_delete(me[0]);
4079     if (me[1]) ast_member_delete(me[1]);
4080     if (me[2]) ast_member_delete(me[2]);
4081     return retval;
4082 }
4083
4084 static bool parser_global_statement(parser_t *parser)
4085 {
4086     ast_value *istype = NULL;
4087     if (parser->tok == TOKEN_IDENT)
4088         istype = parser_find_typedef(parser, parser_tokval(parser), 0);
4089
4090     if (istype || parser->tok == TOKEN_TYPENAME || parser->tok == '.')
4091     {
4092         return parse_variable(parser, NULL, false, CV_NONE, istype);
4093     }
4094     else if (parser->tok == TOKEN_IDENT && !strcmp(parser_tokval(parser), "var"))
4095     {
4096         if (!strcmp(parser_tokval(parser), "var")) {
4097             if (!parser_next(parser)) {
4098                 parseerror(parser, "expected variable declaration after 'var'");
4099                 return false;
4100             }
4101             return parse_variable(parser, NULL, true, CV_VAR, NULL);
4102         }
4103     }
4104     else if (parser->tok == TOKEN_KEYWORD)
4105     {
4106         if (!strcmp(parser_tokval(parser), "const")) {
4107             if (!parser_next(parser)) {
4108                 parseerror(parser, "expected variable declaration after 'const'");
4109                 return false;
4110             }
4111             if (parser->tok == TOKEN_IDENT && !strcmp(parser_tokval(parser), "var")) {
4112                 (void)!parsewarning(parser, WARN_CONST_VAR, "ignoring `var` after const qualifier");
4113                 if (!parser_next(parser)) {
4114                     parseerror(parser, "expected variable declaration after 'const var'");
4115                     return false;
4116                 }
4117             }
4118             return parse_variable(parser, NULL, true, CV_CONST, NULL);
4119         }
4120         else if (!strcmp(parser_tokval(parser), "typedef")) {
4121             if (!parser_next(parser)) {
4122                 parseerror(parser, "expected type definition after 'typedef'");
4123                 return false;
4124             }
4125             return parse_typedef(parser);
4126         }
4127         parseerror(parser, "unrecognized keyword `%s`", parser_tokval(parser));
4128         return false;
4129     }
4130     else if (parser->tok == '$')
4131     {
4132         if (!parser_next(parser)) {
4133             parseerror(parser, "parse error");
4134             return false;
4135         }
4136     }
4137     else
4138     {
4139         parseerror(parser, "unexpected token: %s", parser->lex->tok.value);
4140         return false;
4141     }
4142     return true;
4143 }
4144
4145 static uint16_t progdefs_crc_sum(uint16_t old, const char *str)
4146 {
4147     return util_crc16(old, str, strlen(str));
4148 }
4149
4150 static void progdefs_crc_file(const char *str)
4151 {
4152     /* write to progdefs.h here */
4153     (void)str;
4154 }
4155
4156 static uint16_t progdefs_crc_both(uint16_t old, const char *str)
4157 {
4158     old = progdefs_crc_sum(old, str);
4159     progdefs_crc_file(str);
4160     return old;
4161 }
4162
4163 static void generate_checksum(parser_t *parser)
4164 {
4165     uint16_t   crc = 0xFFFF;
4166     size_t     i;
4167     ast_value *value;
4168
4169         crc = progdefs_crc_both(crc, "\n/* file generated by qcc, do not modify */\n\ntypedef struct\n{");
4170         crc = progdefs_crc_sum(crc, "\tint\tpad[28];\n");
4171         /*
4172         progdefs_crc_file("\tint\tpad;\n");
4173         progdefs_crc_file("\tint\tofs_return[3];\n");
4174         progdefs_crc_file("\tint\tofs_parm0[3];\n");
4175         progdefs_crc_file("\tint\tofs_parm1[3];\n");
4176         progdefs_crc_file("\tint\tofs_parm2[3];\n");
4177         progdefs_crc_file("\tint\tofs_parm3[3];\n");
4178         progdefs_crc_file("\tint\tofs_parm4[3];\n");
4179         progdefs_crc_file("\tint\tofs_parm5[3];\n");
4180         progdefs_crc_file("\tint\tofs_parm6[3];\n");
4181         progdefs_crc_file("\tint\tofs_parm7[3];\n");
4182         */
4183         for (i = 0; i < parser->crc_globals; ++i) {
4184             if (!ast_istype(parser->globals[i], ast_value))
4185                 continue;
4186             value = (ast_value*)(parser->globals[i]);
4187             switch (value->expression.vtype) {
4188                 case TYPE_FLOAT:    crc = progdefs_crc_both(crc, "\tfloat\t"); break;
4189                 case TYPE_VECTOR:   crc = progdefs_crc_both(crc, "\tvec3_t\t"); break;
4190                 case TYPE_STRING:   crc = progdefs_crc_both(crc, "\tstring_t\t"); break;
4191                 case TYPE_FUNCTION: crc = progdefs_crc_both(crc, "\tfunc_t\t"); break;
4192                 default:
4193                     crc = progdefs_crc_both(crc, "\tint\t");
4194                     break;
4195             }
4196             crc = progdefs_crc_both(crc, value->name);
4197             crc = progdefs_crc_both(crc, ";\n");
4198         }
4199         crc = progdefs_crc_both(crc, "} globalvars_t;\n\ntypedef struct\n{\n");
4200         for (i = 0; i < parser->crc_fields; ++i) {
4201             if (!ast_istype(parser->fields[i], ast_value))
4202                 continue;
4203             value = (ast_value*)(parser->fields[i]);
4204             switch (value->expression.next->expression.vtype) {
4205                 case TYPE_FLOAT:    crc = progdefs_crc_both(crc, "\tfloat\t"); break;
4206                 case TYPE_VECTOR:   crc = progdefs_crc_both(crc, "\tvec3_t\t"); break;
4207                 case TYPE_STRING:   crc = progdefs_crc_both(crc, "\tstring_t\t"); break;
4208                 case TYPE_FUNCTION: crc = progdefs_crc_both(crc, "\tfunc_t\t"); break;
4209                 default:
4210                     crc = progdefs_crc_both(crc, "\tint\t");
4211                     break;
4212             }
4213             crc = progdefs_crc_both(crc, value->name);
4214             crc = progdefs_crc_both(crc, ";\n");
4215         }
4216         crc = progdefs_crc_both(crc, "} entvars_t;\n\n");
4217
4218         code_crc = crc;
4219 }
4220
4221 static parser_t *parser;
4222
4223 bool parser_init()
4224 {
4225     size_t i;
4226
4227     parser = (parser_t*)mem_a(sizeof(parser_t));
4228     if (!parser)
4229         return false;
4230
4231     memset(parser, 0, sizeof(*parser));
4232
4233     for (i = 0; i < operator_count; ++i) {
4234         if (operators[i].id == opid1('=')) {
4235             parser->assign_op = operators+i;
4236             break;
4237         }
4238     }
4239     if (!parser->assign_op) {
4240         printf("internal error: initializing parser: failed to find assign operator\n");
4241         mem_d(parser);
4242         return false;
4243     }
4244
4245     vec_push(parser->variables, parser->htfields  = util_htnew(PARSER_HT_SIZE));
4246     vec_push(parser->variables, parser->htglobals = util_htnew(PARSER_HT_SIZE));
4247     vec_push(parser->typedefs, util_htnew(TYPEDEF_HT_SIZE));
4248     vec_push(parser->_blocktypedefs, 0);
4249     return true;
4250 }
4251
4252 bool parser_compile()
4253 {
4254     /* initial lexer/parser state */
4255     parser->lex->flags.noops = true;
4256
4257     if (parser_next(parser))
4258     {
4259         while (parser->tok != TOKEN_EOF && parser->tok < TOKEN_ERROR)
4260         {
4261             if (!parser_global_statement(parser)) {
4262                 if (parser->tok == TOKEN_EOF)
4263                     parseerror(parser, "unexpected eof");
4264                 else if (!parser->errors)
4265                     parseerror(parser, "there have been errors, bailing out");
4266                 lex_close(parser->lex);
4267                 parser->lex = NULL;
4268                 return false;
4269             }
4270         }
4271     } else {
4272         parseerror(parser, "parse error");
4273         lex_close(parser->lex);
4274         parser->lex = NULL;
4275         return false;
4276     }
4277
4278     lex_close(parser->lex);
4279     parser->lex = NULL;
4280
4281     return !parser->errors;
4282 }
4283
4284 bool parser_compile_file(const char *filename)
4285 {
4286     parser->lex = lex_open(filename);
4287     if (!parser->lex) {
4288         con_err("failed to open file \"%s\"\n", filename);
4289         return false;
4290     }
4291     return parser_compile();
4292 }
4293
4294 bool parser_compile_string_len(const char *name, const char *str, size_t len)
4295 {
4296     parser->lex = lex_open_string(str, len, name);
4297     if (!parser->lex) {
4298         con_err("failed to create lexer for string \"%s\"\n", name);
4299         return false;
4300     }
4301     return parser_compile();
4302 }
4303
4304 bool parser_compile_string(const char *name, const char *str)
4305 {
4306     parser->lex = lex_open_string(str, strlen(str), name);
4307     if (!parser->lex) {
4308         con_err("failed to create lexer for string \"%s\"\n", name);
4309         return false;
4310     }
4311     return parser_compile();
4312 }
4313
4314 void parser_cleanup()
4315 {
4316     size_t i;
4317     for (i = 0; i < vec_size(parser->accessors); ++i) {
4318         ast_delete(parser->accessors[i]->constval.vfunc);
4319         parser->accessors[i]->constval.vfunc = NULL;
4320         ast_delete(parser->accessors[i]);
4321     }
4322     for (i = 0; i < vec_size(parser->functions); ++i) {
4323         ast_delete(parser->functions[i]);
4324     }
4325     for (i = 0; i < vec_size(parser->imm_vector); ++i) {
4326         ast_delete(parser->imm_vector[i]);
4327     }
4328     for (i = 0; i < vec_size(parser->imm_string); ++i) {
4329         ast_delete(parser->imm_string[i]);
4330     }
4331     for (i = 0; i < vec_size(parser->imm_float); ++i) {
4332         ast_delete(parser->imm_float[i]);
4333     }
4334     for (i = 0; i < vec_size(parser->fields); ++i) {
4335         ast_delete(parser->fields[i]);
4336     }
4337     for (i = 0; i < vec_size(parser->globals); ++i) {
4338         ast_delete(parser->globals[i]);
4339     }
4340     vec_free(parser->accessors);
4341     vec_free(parser->functions);
4342     vec_free(parser->imm_vector);
4343     vec_free(parser->imm_string);
4344     vec_free(parser->imm_float);
4345     vec_free(parser->globals);
4346     vec_free(parser->fields);
4347
4348     for (i = 0; i < vec_size(parser->variables); ++i)
4349         util_htdel(parser->variables[i]);
4350     vec_free(parser->variables);
4351     vec_free(parser->_blocklocals);
4352     vec_free(parser->_locals);
4353
4354     for (i = 0; i < vec_size(parser->_typedefs); ++i)
4355         ast_delete(parser->_typedefs[i]);
4356     vec_free(parser->_typedefs);
4357     for (i = 0; i < vec_size(parser->typedefs); ++i)
4358         util_htdel(parser->typedefs[i]);
4359     vec_free(parser->typedefs);
4360     vec_free(parser->_blocktypedefs);
4361
4362     vec_free(parser->labels);
4363     vec_free(parser->gotos);
4364
4365     mem_d(parser);
4366 }
4367
4368 bool parser_finish(const char *output)
4369 {
4370     size_t i;
4371     ir_builder *ir;
4372     bool retval = true;
4373
4374     if (!parser->errors)
4375     {
4376         ir = ir_builder_new("gmqcc_out");
4377         if (!ir) {
4378             con_out("failed to allocate builder\n");
4379             return false;
4380         }
4381
4382         for (i = 0; i < vec_size(parser->fields); ++i) {
4383             ast_value *field;
4384             bool hasvalue;
4385             if (!ast_istype(parser->fields[i], ast_value))
4386                 continue;
4387             field = (ast_value*)parser->fields[i];
4388             hasvalue = field->hasvalue;
4389             field->hasvalue = false;
4390             if (!ast_global_codegen((ast_value*)field, ir, true)) {
4391                 con_out("failed to generate field %s\n", field->name);
4392                 ir_builder_delete(ir);
4393                 return false;
4394             }
4395             if (hasvalue) {
4396                 ir_value *ifld;
4397                 ast_expression *subtype;
4398                 field->hasvalue = true;
4399                 subtype = field->expression.next;
4400                 ifld = ir_builder_create_field(ir, field->name, subtype->expression.vtype);
4401                 if (subtype->expression.vtype == TYPE_FIELD)
4402                     ifld->fieldtype = subtype->expression.next->expression.vtype;
4403                 else if (subtype->expression.vtype == TYPE_FUNCTION)
4404                     ifld->outtype = subtype->expression.next->expression.vtype;
4405                 (void)!ir_value_set_field(field->ir_v, ifld);
4406             }
4407         }
4408         for (i = 0; i < vec_size(parser->globals); ++i) {
4409             ast_value *asvalue;
4410             if (!ast_istype(parser->globals[i], ast_value))
4411                 continue;
4412             asvalue = (ast_value*)(parser->globals[i]);
4413             if (!asvalue->uses && !asvalue->hasvalue && asvalue->expression.vtype != TYPE_FUNCTION) {
4414                 if (strcmp(asvalue->name, "end_sys_globals") &&
4415                     strcmp(asvalue->name, "end_sys_fields"))
4416                 {
4417                     retval = retval && !genwarning(ast_ctx(asvalue), WARN_UNUSED_VARIABLE,
4418                                                    "unused global: `%s`", asvalue->name);
4419                 }
4420             }
4421             if (!ast_global_codegen(asvalue, ir, false)) {
4422                 con_out("failed to generate global %s\n", asvalue->name);
4423                 ir_builder_delete(ir);
4424                 return false;
4425             }
4426         }
4427         for (i = 0; i < vec_size(parser->imm_float); ++i) {
4428             if (!ast_global_codegen(parser->imm_float[i], ir, false)) {
4429                 con_out("failed to generate global %s\n", parser->imm_float[i]->name);
4430                 ir_builder_delete(ir);
4431                 return false;
4432             }
4433         }
4434         for (i = 0; i < vec_size(parser->imm_string); ++i) {
4435             if (!ast_global_codegen(parser->imm_string[i], ir, false)) {
4436                 con_out("failed to generate global %s\n", parser->imm_string[i]->name);
4437                 ir_builder_delete(ir);
4438                 return false;
4439             }
4440         }
4441         for (i = 0; i < vec_size(parser->imm_vector); ++i) {
4442             if (!ast_global_codegen(parser->imm_vector[i], ir, false)) {
4443                 con_out("failed to generate global %s\n", parser->imm_vector[i]->name);
4444                 ir_builder_delete(ir);
4445                 return false;
4446             }
4447         }
4448         for (i = 0; i < vec_size(parser->globals); ++i) {
4449             ast_value *asvalue;
4450             if (!ast_istype(parser->globals[i], ast_value))
4451                 continue;
4452             asvalue = (ast_value*)(parser->globals[i]);
4453             if (asvalue->setter) {
4454                 if (!ast_global_codegen(asvalue->setter, ir, false) ||
4455                     !ast_function_codegen(asvalue->setter->constval.vfunc, ir) ||
4456                     !ir_function_finalize(asvalue->setter->constval.vfunc->ir_func))
4457                 {
4458                     printf("failed to generate setter for %s\n", asvalue->name);
4459                     ir_builder_delete(ir);
4460                     return false;
4461                 }
4462             }
4463             if (asvalue->getter) {
4464                 if (!ast_global_codegen(asvalue->getter, ir, false) ||
4465                     !ast_function_codegen(asvalue->getter->constval.vfunc, ir) ||
4466                     !ir_function_finalize(asvalue->getter->constval.vfunc->ir_func))
4467                 {
4468                     printf("failed to generate getter for %s\n", asvalue->name);
4469                     ir_builder_delete(ir);
4470                     return false;
4471                 }
4472             }
4473         }
4474         for (i = 0; i < vec_size(parser->fields); ++i) {
4475             ast_value *asvalue;
4476             asvalue = (ast_value*)(parser->fields[i]->expression.next);
4477
4478             if (!ast_istype((ast_expression*)asvalue, ast_value))
4479                 continue;
4480             if (asvalue->expression.vtype != TYPE_ARRAY)
4481                 continue;
4482             if (asvalue->setter) {
4483                 if (!ast_global_codegen(asvalue->setter, ir, false) ||
4484                     !ast_function_codegen(asvalue->setter->constval.vfunc, ir) ||
4485                     !ir_function_finalize(asvalue->setter->constval.vfunc->ir_func))
4486                 {
4487                     printf("failed to generate setter for %s\n", asvalue->name);
4488                     ir_builder_delete(ir);
4489                     return false;
4490                 }
4491             }
4492             if (asvalue->getter) {
4493                 if (!ast_global_codegen(asvalue->getter, ir, false) ||
4494                     !ast_function_codegen(asvalue->getter->constval.vfunc, ir) ||
4495                     !ir_function_finalize(asvalue->getter->constval.vfunc->ir_func))
4496                 {
4497                     printf("failed to generate getter for %s\n", asvalue->name);
4498                     ir_builder_delete(ir);
4499                     return false;
4500                 }
4501             }
4502         }
4503         for (i = 0; i < vec_size(parser->functions); ++i) {
4504             if (!ast_function_codegen(parser->functions[i], ir)) {
4505                 con_out("failed to generate function %s\n", parser->functions[i]->name);
4506                 ir_builder_delete(ir);
4507                 return false;
4508             }
4509         }
4510         if (opts_dump)
4511             ir_builder_dump(ir, con_out);
4512         for (i = 0; i < vec_size(parser->functions); ++i) {
4513             if (!ir_function_finalize(parser->functions[i]->ir_func)) {
4514                 con_out("failed to finalize function %s\n", parser->functions[i]->name);
4515                 ir_builder_delete(ir);
4516                 return false;
4517             }
4518         }
4519
4520         if (retval) {
4521             if (opts_dumpfin)
4522                 ir_builder_dump(ir, con_out);
4523
4524             generate_checksum(parser);
4525
4526             if (!ir_builder_generate(ir, output)) {
4527                 con_out("*** failed to generate output file\n");
4528                 ir_builder_delete(ir);
4529                 return false;
4530             }
4531         }
4532
4533         ir_builder_delete(ir);
4534         return retval;
4535     }
4536
4537     con_out("*** there were compile errors\n");
4538     return false;
4539 }