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