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