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