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