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