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