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