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