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