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