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