]> de.git.xonotic.org Git - xonotic/gmqcc.git/blob - parser.c
Removing some code duplication
[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     ast_block      *body = NULL;
2400
2401     fval = ast_value_new(ast_ctx(array), funcname, TYPE_FUNCTION);
2402     if (!fval) {
2403         parseerror(parser, "failed to create accessor function value");
2404         return false;
2405     }
2406
2407     func = ast_function_new(ast_ctx(array), funcname, fval);
2408     if (!func) {
2409         ast_delete(fval);
2410         parseerror(parser, "failed to create accessor function node");
2411         return false;
2412     }
2413
2414     body = ast_block_new(ast_ctx(array));
2415     if (!body) {
2416         parseerror(parser, "failed to create block for array accessor");
2417         ast_delete(fval);
2418         ast_delete(func);
2419         return false;
2420     }
2421
2422     vec_push(func->blocks, body);
2423     *out = fval;
2424
2425     return true;
2426 }
2427
2428 static bool parser_create_array_setter(parser_t *parser, ast_value *array, const char *funcname)
2429 {
2430     ast_expression *root = NULL;
2431     ast_value      *index = NULL;
2432     ast_value      *value = NULL;
2433     ast_function   *func;
2434     ast_value      *fval;
2435
2436     if (!ast_istype(array->expression.next, ast_value)) {
2437         parseerror(parser, "internal error: array accessor needs to build an ast_value with a copy of the element type");
2438         return false;
2439     }
2440
2441     if (!parser_create_array_accessor(parser, array, funcname, &fval))
2442         return false;
2443     func = fval->constval.vfunc;
2444     fval->expression.next = (ast_expression*)ast_value_new(ast_ctx(array), "<void>", TYPE_VOID);
2445
2446     index = ast_value_new(ast_ctx(array), "index", TYPE_FLOAT);
2447     value = ast_value_copy((ast_value*)array->expression.next);
2448
2449     if (!index || !value) {
2450         parseerror(parser, "failed to create locals for array accessor");
2451         goto cleanup;
2452     }
2453     (void)!ast_value_set_name(value, "value"); /* not important */
2454     vec_push(fval->expression.params, index);
2455     vec_push(fval->expression.params, value);
2456
2457     root = array_setter_node(parser, array, index, value, 0, array->expression.count);
2458     if (!root) {
2459         parseerror(parser, "failed to build accessor search tree");
2460         goto cleanup;
2461     }
2462
2463     vec_push(func->blocks[0]->exprs, root);
2464     array->setter = fval;
2465     return true;
2466 cleanup:
2467     if (index) ast_delete(index);
2468     if (value) ast_delete(value);
2469     if (root)  ast_delete(root);
2470     ast_delete(func);
2471     ast_delete(fval);
2472     return false;
2473 }
2474
2475 static bool parser_create_array_field_setter(parser_t *parser, ast_value *array, const char *funcname)
2476 {
2477     ast_expression *root = 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     entity = ast_value_new(ast_ctx(array), "entity", TYPE_ENTITY);
2495     index  = ast_value_new(ast_ctx(array), "index",  TYPE_FLOAT);
2496     value  = ast_value_copy((ast_value*)array->expression.next);
2497     if (!entity || !index || !value) {
2498         parseerror(parser, "failed to create locals for array accessor");
2499         goto cleanup;
2500     }
2501     (void)!ast_value_set_name(value, "value"); /* not important */
2502     vec_push(fval->expression.params, entity);
2503     vec_push(fval->expression.params, index);
2504     vec_push(fval->expression.params, value);
2505
2506     root = array_field_setter_node(parser, array, entity, index, value, 0, array->expression.count);
2507     if (!root) {
2508         parseerror(parser, "failed to build accessor search tree");
2509         goto cleanup;
2510     }
2511
2512     vec_push(func->blocks[0]->exprs, root);
2513     array->setter = fval;
2514     return true;
2515 cleanup:
2516     if (entity) ast_delete(entity);
2517     if (index)  ast_delete(index);
2518     if (value)  ast_delete(value);
2519     if (root)   ast_delete(root);
2520     ast_delete(func);
2521     ast_delete(fval);
2522     return false;
2523 }
2524
2525 static bool parser_create_array_getter(parser_t *parser, ast_value *array, const ast_expression *elemtype, const char *funcname)
2526 {
2527     ast_expression *root = NULL;
2528     ast_value      *index = NULL;
2529     ast_value      *fval;
2530     ast_function   *func;
2531
2532     /* NOTE: checking array->expression.next rather than elemtype since
2533      * for fields elemtype is a temporary fieldtype.
2534      */
2535     if (!ast_istype(array->expression.next, ast_value)) {
2536         parseerror(parser, "internal error: array accessor needs to build an ast_value with a copy of the element type");
2537         return false;
2538     }
2539
2540     if (!parser_create_array_accessor(parser, array, funcname, &fval))
2541         return false;
2542     func = fval->constval.vfunc;
2543     fval->expression.next = ast_type_copy(ast_ctx(array), elemtype);
2544
2545     index = ast_value_new(ast_ctx(array), "index", TYPE_FLOAT);
2546
2547     if (!index) {
2548         parseerror(parser, "failed to create locals for array accessor");
2549         goto cleanup;
2550     }
2551     vec_push(fval->expression.params, index);
2552
2553     root = array_getter_node(parser, array, index, 0, array->expression.count);
2554     if (!root) {
2555         parseerror(parser, "failed to build accessor search tree");
2556         goto cleanup;
2557     }
2558
2559     vec_push(func->blocks[0]->exprs, root);
2560     array->getter = fval;
2561     return true;
2562 cleanup:
2563     if (index) ast_delete(index);
2564     if (root)  ast_delete(root);
2565     ast_delete(func);
2566     ast_delete(fval);
2567     return false;
2568 }
2569
2570 static ast_value *parse_typename(parser_t *parser, ast_value **storebase);
2571 static ast_value *parse_parameter_list(parser_t *parser, ast_value *var)
2572 {
2573     lex_ctx     ctx;
2574     size_t      i;
2575     ast_value **params;
2576     ast_value  *param;
2577     ast_value  *fval;
2578     bool        first = true;
2579     bool        variadic = false;
2580
2581     ctx = parser_ctx(parser);
2582
2583     /* for the sake of less code we parse-in in this function */
2584     if (!parser_next(parser)) {
2585         parseerror(parser, "expected parameter list");
2586         return NULL;
2587     }
2588
2589     params = NULL;
2590
2591     /* parse variables until we hit a closing paren */
2592     while (parser->tok != ')') {
2593         if (!first) {
2594             /* there must be commas between them */
2595             if (parser->tok != ',') {
2596                 parseerror(parser, "expected comma or end of parameter list");
2597                 goto on_error;
2598             }
2599             if (!parser_next(parser)) {
2600                 parseerror(parser, "expected parameter");
2601                 goto on_error;
2602             }
2603         }
2604         first = false;
2605
2606         if (parser->tok == TOKEN_DOTS) {
2607             /* '...' indicates a varargs function */
2608             variadic = true;
2609             if (!parser_next(parser)) {
2610                 parseerror(parser, "expected parameter");
2611                 return NULL;
2612             }
2613             if (parser->tok != ')') {
2614                 parseerror(parser, "`...` must be the last parameter of a variadic function declaration");
2615                 goto on_error;
2616             }
2617         }
2618         else
2619         {
2620             /* for anything else just parse a typename */
2621             param = parse_typename(parser, NULL);
2622             if (!param)
2623                 goto on_error;
2624             vec_push(params, param);
2625             if (param->expression.vtype >= TYPE_VARIANT) {
2626                 char typename[1024];
2627                 ast_type_to_string((ast_expression*)param, typename, sizeof(typename));
2628                 parseerror(parser, "type not supported as part of a parameter list: %s", typename);
2629                 goto on_error;
2630             }
2631         }
2632     }
2633
2634     /* sanity check */
2635     if (vec_size(params) > 8)
2636         parseerror(parser, "more than 8 parameters are currently not supported");
2637
2638     /* parse-out */
2639     if (!parser_next(parser)) {
2640         parseerror(parser, "parse error after typename");
2641         goto on_error;
2642     }
2643
2644     /* now turn 'var' into a function type */
2645     fval = ast_value_new(ctx, "<type()>", TYPE_FUNCTION);
2646     fval->expression.next     = (ast_expression*)var;
2647     fval->expression.variadic = variadic;
2648     var = fval;
2649
2650     var->expression.params = params;
2651     params = NULL;
2652
2653     return var;
2654
2655 on_error:
2656     ast_delete(var);
2657     for (i = 0; i < vec_size(params); ++i)
2658         ast_delete(params[i]);
2659     vec_free(params);
2660     return NULL;
2661 }
2662
2663 static ast_value *parse_arraysize(parser_t *parser, ast_value *var)
2664 {
2665     ast_expression *cexp;
2666     ast_value      *cval, *tmp;
2667     lex_ctx ctx;
2668
2669     ctx = parser_ctx(parser);
2670
2671     if (!parser_next(parser)) {
2672         ast_delete(var);
2673         parseerror(parser, "expected array-size");
2674         return NULL;
2675     }
2676
2677     cexp = parse_expression_leave(parser, true);
2678
2679     if (!cexp || !ast_istype(cexp, ast_value)) {
2680         if (cexp)
2681             ast_unref(cexp);
2682         ast_delete(var);
2683         parseerror(parser, "expected array-size as constant positive integer");
2684         return NULL;
2685     }
2686     cval = (ast_value*)cexp;
2687
2688     tmp = ast_value_new(ctx, "<type[]>", TYPE_ARRAY);
2689     tmp->expression.next = (ast_expression*)var;
2690     var = tmp;
2691
2692     if (cval->expression.vtype == TYPE_INTEGER)
2693         tmp->expression.count = cval->constval.vint;
2694     else if (cval->expression.vtype == TYPE_FLOAT)
2695         tmp->expression.count = cval->constval.vfloat;
2696     else {
2697         ast_unref(cexp);
2698         ast_delete(var);
2699         parseerror(parser, "array-size must be a positive integer constant");
2700         return NULL;
2701     }
2702     ast_unref(cexp);
2703
2704     if (parser->tok != ']') {
2705         ast_delete(var);
2706         parseerror(parser, "expected ']' after array-size");
2707         return NULL;
2708     }
2709     if (!parser_next(parser)) {
2710         ast_delete(var);
2711         parseerror(parser, "error after parsing array size");
2712         return NULL;
2713     }
2714     return var;
2715 }
2716
2717 /* Parse a complete typename.
2718  * for single-variables (ie. function parameters or typedefs) storebase should be NULL
2719  * but when parsing variables separated by comma
2720  * 'storebase' should point to where the base-type should be kept.
2721  * The base type makes up every bit of type information which comes *before* the
2722  * variable name.
2723  *
2724  * The following will be parsed in its entirety:
2725  *     void() foo()
2726  * The 'basetype' in this case is 'void()'
2727  * and if there's a comma after it, say:
2728  *     void() foo(), bar
2729  * then the type-information 'void()' can be stored in 'storebase'
2730  */
2731 static ast_value *parse_typename(parser_t *parser, ast_value **storebase)
2732 {
2733     ast_value *var, *tmp;
2734     lex_ctx    ctx;
2735
2736     const char *name = NULL;
2737     bool        isfield  = false;
2738     bool        wasarray = false;
2739
2740     ctx = parser_ctx(parser);
2741
2742     /* types may start with a dot */
2743     if (parser->tok == '.') {
2744         isfield = true;
2745         /* if we parsed a dot we need a typename now */
2746         if (!parser_next(parser)) {
2747             parseerror(parser, "expected typename for field definition");
2748             return NULL;
2749         }
2750         if (parser->tok != TOKEN_TYPENAME) {
2751             parseerror(parser, "expected typename");
2752             return NULL;
2753         }
2754     }
2755
2756     /* generate the basic type value */
2757     var = ast_value_new(ctx, "<type>", parser_token(parser)->constval.t);
2758     /* do not yet turn into a field - remember:
2759      * .void() foo; is a field too
2760      * .void()() foo; is a function
2761      */
2762
2763     /* parse on */
2764     if (!parser_next(parser)) {
2765         ast_delete(var);
2766         parseerror(parser, "parse error after typename");
2767         return NULL;
2768     }
2769
2770     /* an opening paren now starts the parameter-list of a function
2771      * this is where original-QC has parameter lists.
2772      * We allow a single parameter list here.
2773      * Much like fteqcc we don't allow `float()() x`
2774      */
2775     if (parser->tok == '(') {
2776         var = parse_parameter_list(parser, var);
2777         if (!var)
2778             return NULL;
2779     }
2780
2781     /* store the base if requested */
2782     if (storebase) {
2783         *storebase = ast_value_copy(var);
2784         if (isfield) {
2785             tmp = ast_value_new(ctx, "<type:f>", TYPE_FIELD);
2786             tmp->expression.next = (ast_expression*)*storebase;
2787             *storebase = tmp;
2788         }
2789     }
2790
2791     /* there may be a name now */
2792     if (parser->tok == TOKEN_IDENT) {
2793         name = util_strdup(parser_tokval(parser));
2794         /* parse on */
2795         if (!parser_next(parser)) {
2796             ast_delete(var);
2797             parseerror(parser, "error after variable or field declaration");
2798             return NULL;
2799         }
2800     }
2801
2802     /* now this may be an array */
2803     if (parser->tok == '[') {
2804         wasarray = true;
2805         var = parse_arraysize(parser, var);
2806         if (!var)
2807             return NULL;
2808     }
2809
2810     /* This is the point where we can turn it into a field */
2811     if (isfield) {
2812         /* turn it into a field if desired */
2813         tmp = ast_value_new(ctx, "<type:f>", TYPE_FIELD);
2814         tmp->expression.next = (ast_expression*)var;
2815         var = tmp;
2816     }
2817
2818     /* now there may be function parens again */
2819     if (parser->tok == '(' && opts_standard == COMPILER_QCC)
2820         parseerror(parser, "C-style function syntax is not allowed in -std=qcc");
2821     if (parser->tok == '(' && wasarray)
2822         parseerror(parser, "arrays as part of a return type is not supported");
2823     while (parser->tok == '(') {
2824         var = parse_parameter_list(parser, var);
2825         if (!var) {
2826             if (name)
2827                 mem_d((void*)name);
2828             ast_delete(var);
2829             return NULL;
2830         }
2831     }
2832
2833     /* finally name it */
2834     if (name) {
2835         if (!ast_value_set_name(var, name)) {
2836             ast_delete(var);
2837             parseerror(parser, "internal error: failed to set name");
2838             return NULL;
2839         }
2840         /* free the name, ast_value_set_name duplicates */
2841         mem_d((void*)name);
2842     }
2843
2844     return var;
2845 }
2846
2847 static bool parse_variable(parser_t *parser, ast_block *localblock, bool nofields)
2848 {
2849     ast_value *var;
2850     ast_value *proto;
2851     ast_expression *old;
2852     bool       was_end;
2853     size_t     i;
2854
2855     ast_value *basetype = NULL;
2856     bool      retval    = true;
2857     bool      isparam   = false;
2858     bool      isvector  = false;
2859     bool      cleanvar  = true;
2860     bool      wasarray  = false;
2861
2862     varentry_t varent, ve[3];
2863
2864     /* get the first complete variable */
2865     var = parse_typename(parser, &basetype);
2866     if (!var) {
2867         if (basetype)
2868             ast_delete(basetype);
2869         return false;
2870     }
2871
2872     memset(&varent, 0, sizeof(varent));
2873     memset(&ve, 0, sizeof(ve));
2874
2875     while (true) {
2876         proto = NULL;
2877         wasarray = false;
2878
2879         /* Part 0: finish the type */
2880         if (parser->tok == '(') {
2881             if (opts_standard == COMPILER_QCC)
2882                 parseerror(parser, "C-style function syntax is not allowed in -std=qcc");
2883             var = parse_parameter_list(parser, var);
2884             if (!var) {
2885                 retval = false;
2886                 goto cleanup;
2887             }
2888         }
2889         /* we only allow 1-dimensional arrays */
2890         if (parser->tok == '[') {
2891             wasarray = true;
2892             var = parse_arraysize(parser, var);
2893             if (!var) {
2894                 retval = false;
2895                 goto cleanup;
2896             }
2897         }
2898         if (parser->tok == '(' && wasarray) {
2899             parseerror(parser, "arrays as part of a return type is not supported");
2900             /* we'll still parse the type completely for now */
2901         }
2902         /* for functions returning functions */
2903         while (parser->tok == '(') {
2904             if (opts_standard == COMPILER_QCC)
2905                 parseerror(parser, "C-style function syntax is not allowed in -std=qcc");
2906             var = parse_parameter_list(parser, var);
2907             if (!var) {
2908                 retval = false;
2909                 goto cleanup;
2910             }
2911         }
2912
2913         /* Part 1:
2914          * check for validity: (end_sys_..., multiple-definitions, prototypes, ...)
2915          * Also: if there was a prototype, `var` will be deleted and set to `proto` which
2916          * is then filled with the previous definition and the parameter-names replaced.
2917          */
2918         if (!localblock) {
2919             /* Deal with end_sys_ vars */
2920             was_end = false;
2921             if (!strcmp(var->name, "end_sys_globals")) {
2922                 parser->crc_globals = vec_size(parser->globals);
2923                 was_end = true;
2924             }
2925             else if (!strcmp(var->name, "end_sys_fields")) {
2926                 parser->crc_fields = vec_size(parser->fields);
2927                 was_end = true;
2928             }
2929             if (was_end && var->expression.vtype == TYPE_FIELD) {
2930                 if (parsewarning(parser, WARN_END_SYS_FIELDS,
2931                                  "global '%s' hint should not be a field",
2932                                  parser_tokval(parser)))
2933                 {
2934                     retval = false;
2935                     goto cleanup;
2936                 }
2937             }
2938
2939             if (!nofields && var->expression.vtype == TYPE_FIELD)
2940             {
2941                 /* deal with field declarations */
2942                 old = parser_find_field(parser, var->name);
2943                 if (old) {
2944                     if (parsewarning(parser, WARN_FIELD_REDECLARED, "field `%s` already declared here: %s:%i",
2945                                      var->name, ast_ctx(old).file, (int)ast_ctx(old).line))
2946                     {
2947                         retval = false;
2948                         goto cleanup;
2949                     }
2950                     ast_delete(var);
2951                     var = NULL;
2952                     goto skipvar;
2953                     /*
2954                     parseerror(parser, "field `%s` already declared here: %s:%i",
2955                                var->name, ast_ctx(old).file, ast_ctx(old).line);
2956                     retval = false;
2957                     goto cleanup;
2958                     */
2959                 }
2960                 if (opts_standard == COMPILER_QCC &&
2961                     (old = parser_find_global(parser, var->name)))
2962                 {
2963                     parseerror(parser, "cannot declare a field and a global of the same name with -std=qcc");
2964                     parseerror(parser, "field `%s` already declared here: %s:%i",
2965                                var->name, ast_ctx(old).file, ast_ctx(old).line);
2966                     retval = false;
2967                     goto cleanup;
2968                 }
2969             }
2970             else
2971             {
2972                 /* deal with other globals */
2973                 old = parser_find_global(parser, var->name);
2974                 if (old && var->expression.vtype == TYPE_FUNCTION && old->expression.vtype == TYPE_FUNCTION)
2975                 {
2976                     /* This is a function which had a prototype */
2977                     if (!ast_istype(old, ast_value)) {
2978                         parseerror(parser, "internal error: prototype is not an ast_value");
2979                         retval = false;
2980                         goto cleanup;
2981                     }
2982                     proto = (ast_value*)old;
2983                     if (!ast_compare_type((ast_expression*)proto, (ast_expression*)var)) {
2984                         parseerror(parser, "conflicting types for `%s`, previous declaration was here: %s:%i",
2985                                    proto->name,
2986                                    ast_ctx(proto).file, ast_ctx(proto).line);
2987                         retval = false;
2988                         goto cleanup;
2989                     }
2990                     /* we need the new parameter-names */
2991                     for (i = 0; i < vec_size(proto->expression.params); ++i)
2992                         ast_value_set_name(proto->expression.params[i], var->expression.params[i]->name);
2993                     ast_delete(var);
2994                     var = proto;
2995                 }
2996                 else
2997                 {
2998                     /* other globals */
2999                     if (old) {
3000                         parseerror(parser, "global `%s` already declared here: %s:%i",
3001                                    var->name, ast_ctx(old).file, ast_ctx(old).line);
3002                         retval = false;
3003                         goto cleanup;
3004                     }
3005                     if (opts_standard == COMPILER_QCC &&
3006                         (old = parser_find_field(parser, var->name)))
3007                     {
3008                         parseerror(parser, "cannot declare a field and a global of the same name with -std=qcc");
3009                         parseerror(parser, "global `%s` already declared here: %s:%i",
3010                                    var->name, ast_ctx(old).file, ast_ctx(old).line);
3011                         retval = false;
3012                         goto cleanup;
3013                     }
3014                 }
3015             }
3016         }
3017         else /* it's not a global */
3018         {
3019             old = parser_find_local(parser, var->name, parser->blocklocal, &isparam);
3020             if (old && !isparam) {
3021                 parseerror(parser, "local `%s` already declared here: %s:%i",
3022                            var->name, ast_ctx(old).file, (int)ast_ctx(old).line);
3023                 retval = false;
3024                 goto cleanup;
3025             }
3026             old = parser_find_local(parser, var->name, 0, &isparam);
3027             if (old && isparam) {
3028                 if (parsewarning(parser, WARN_LOCAL_SHADOWS,
3029                                  "local `%s` is shadowing a parameter", var->name))
3030                 {
3031                     parseerror(parser, "local `%s` already declared here: %s:%i",
3032                                var->name, ast_ctx(old).file, (int)ast_ctx(old).line);
3033                     retval = false;
3034                     goto cleanup;
3035                 }
3036                 if (opts_standard != COMPILER_GMQCC) {
3037                     ast_delete(var);
3038                     var = NULL;
3039                     goto skipvar;
3040                 }
3041             }
3042         }
3043
3044         /* Part 2:
3045          * Create the global/local, and deal with vector types.
3046          */
3047         if (!proto) {
3048             if (var->expression.vtype == TYPE_VECTOR)
3049                 isvector = true;
3050             else if (var->expression.vtype == TYPE_FIELD &&
3051                      var->expression.next->expression.vtype == TYPE_VECTOR)
3052                 isvector = true;
3053
3054             if (isvector) {
3055                 if (!create_vector_members(parser, var, ve)) {
3056                     retval = false;
3057                     goto cleanup;
3058                 }
3059             }
3060
3061             varent.name = util_strdup(var->name);
3062             varent.var  = (ast_expression*)var;
3063
3064             if (!localblock) {
3065                 /* deal with global variables, fields, functions */
3066                 if (!nofields && var->expression.vtype == TYPE_FIELD) {
3067                     vec_push(parser->fields, varent);
3068                     if (isvector) {
3069                         for (i = 0; i < 3; ++i)
3070                             vec_push(parser->fields, ve[i]);
3071                     }
3072                 }
3073                 else {
3074                     vec_push(parser->globals, varent);
3075                     if (isvector) {
3076                         for (i = 0; i < 3; ++i)
3077                             vec_push(parser->globals, ve[i]);
3078                     }
3079                 }
3080             } else {
3081                 vec_push(parser->locals, varent);
3082                 vec_push(localblock->locals, var);
3083                 if (isvector) {
3084                     for (i = 0; i < 3; ++i) {
3085                         vec_push(parser->locals, ve[i]);
3086                         ast_block_collect(localblock, ve[i].var);
3087                         ve[i].var = NULL; /* from here it's being collected in the block */
3088                     }
3089                 }
3090             }
3091
3092             varent.name = NULL;
3093             ve[0].name = ve[1].name = ve[2].name = NULL;
3094             ve[0].var  = ve[1].var  = ve[2].var  = NULL;
3095             cleanvar = false;
3096         }
3097         /* Part 2.2
3098          * deal with arrays
3099          */
3100         if (var->expression.vtype == TYPE_ARRAY) {
3101             char name[1024];
3102             snprintf(name, sizeof(name), "%s##SET", var->name);
3103             if (!parser_create_array_setter(parser, var, name))
3104                 goto cleanup;
3105             snprintf(name, sizeof(name), "%s##GET", var->name);
3106             if (!parser_create_array_getter(parser, var, var->expression.next, name))
3107                 goto cleanup;
3108         }
3109         else if (!localblock && !nofields &&
3110                  var->expression.vtype == TYPE_FIELD &&
3111                  var->expression.next->expression.vtype == TYPE_ARRAY)
3112         {
3113             char name[1024];
3114             ast_expression *telem;
3115             ast_value      *tfield;
3116             ast_value      *array = (ast_value*)var->expression.next;
3117
3118             if (!ast_istype(var->expression.next, ast_value)) {
3119                 parseerror(parser, "internal error: field element type must be an ast_value");
3120                 goto cleanup;
3121             }
3122
3123             snprintf(name, sizeof(name), "%s##SETF", var->name);
3124             if (!parser_create_array_field_setter(parser, array, name))
3125                 goto cleanup;
3126
3127             telem = ast_type_copy(ast_ctx(var), array->expression.next);
3128             tfield = ast_value_new(ast_ctx(var), "<.type>", TYPE_FIELD);
3129             tfield->expression.next = telem;
3130             snprintf(name, sizeof(name), "%s##GETFP", var->name);
3131             if (!parser_create_array_getter(parser, array, (ast_expression*)tfield, name)) {
3132                 ast_delete(tfield);
3133                 goto cleanup;
3134             }
3135             ast_delete(tfield);
3136         }
3137
3138 skipvar:
3139         if (parser->tok == ';') {
3140             ast_delete(basetype);
3141             if (!parser_next(parser)) {
3142                 parseerror(parser, "error after variable declaration");
3143                 return false;
3144             }
3145             return true;
3146         }
3147
3148         if (parser->tok == ',')
3149             goto another;
3150
3151         if (!var || (!localblock && !nofields && basetype->expression.vtype == TYPE_FIELD)) {
3152             parseerror(parser, "missing comma or semicolon while parsing variables");
3153             break;
3154         }
3155
3156         if (localblock && opts_standard == COMPILER_QCC) {
3157             if (parsewarning(parser, WARN_LOCAL_CONSTANTS,
3158                              "initializing expression turns variable `%s` into a constant in this standard",
3159                              var->name) )
3160             {
3161                 break;
3162             }
3163         }
3164
3165         if (parser->tok != '{') {
3166             if (parser->tok != '=') {
3167                 parseerror(parser, "missing semicolon or initializer");
3168                 break;
3169             }
3170
3171             if (!parser_next(parser)) {
3172                 parseerror(parser, "error parsing initializer");
3173                 break;
3174             }
3175         }
3176         else if (opts_standard == COMPILER_QCC) {
3177             parseerror(parser, "expected '=' before function body in this standard");
3178         }
3179
3180         if (parser->tok == '#') {
3181             ast_function *func;
3182
3183             if (localblock) {
3184                 parseerror(parser, "cannot declare builtins within functions");
3185                 break;
3186             }
3187             if (var->expression.vtype != TYPE_FUNCTION) {
3188                 parseerror(parser, "unexpected builtin number, '%s' is not a function", var->name);
3189                 break;
3190             }
3191             if (!parser_next(parser)) {
3192                 parseerror(parser, "expected builtin number");
3193                 break;
3194             }
3195             if (parser->tok != TOKEN_INTCONST) {
3196                 parseerror(parser, "builtin number must be an integer constant");
3197                 break;
3198             }
3199             if (parser_token(parser)->constval.i <= 0) {
3200                 parseerror(parser, "builtin number must be an integer greater than zero");
3201                 break;
3202             }
3203
3204             func = ast_function_new(ast_ctx(var), var->name, var);
3205             if (!func) {
3206                 parseerror(parser, "failed to allocate function for `%s`", var->name);
3207                 break;
3208             }
3209             vec_push(parser->functions, func);
3210
3211             func->builtin = -parser_token(parser)->constval.i;
3212
3213             if (!parser_next(parser)) {
3214                 parseerror(parser, "expected comma or semicolon");
3215                 ast_function_delete(func);
3216                 var->constval.vfunc = NULL;
3217                 break;
3218             }
3219         }
3220         else if (parser->tok == '{' || parser->tok == '[')
3221         {
3222             if (localblock) {
3223                 parseerror(parser, "cannot declare functions within functions");
3224                 break;
3225             }
3226
3227             if (!parse_function_body(parser, var))
3228                 break;
3229             ast_delete(basetype);
3230             return true;
3231         } else {
3232             ast_expression *cexp;
3233             ast_value      *cval;
3234
3235             cexp = parse_expression_leave(parser, true);
3236             if (!cexp)
3237                 break;
3238
3239             if (!localblock) {
3240                 cval = (ast_value*)cexp;
3241                 if (!ast_istype(cval, ast_value) || !cval->isconst)
3242                     parseerror(parser, "cannot initialize a global constant variable with a non-constant expression");
3243                 else
3244                 {
3245                     var->isconst = true;
3246                     if (cval->expression.vtype == TYPE_STRING)
3247                         var->constval.vstring = parser_strdup(cval->constval.vstring);
3248                     else
3249                         memcpy(&var->constval, &cval->constval, sizeof(var->constval));
3250                     ast_unref(cval);
3251                 }
3252             } else {
3253                 shunt sy = { NULL, NULL };
3254                 vec_push(sy.out, syexp(ast_ctx(var), (ast_expression*)var));
3255                 vec_push(sy.out, syexp(ast_ctx(cexp), (ast_expression*)cexp));
3256                 vec_push(sy.ops, syop(ast_ctx(var), parser->assign_op));
3257                 if (!parser_sy_pop(parser, &sy))
3258                     ast_unref(cexp);
3259                 else {
3260                     if (vec_size(sy.out) != 1 && vec_size(sy.ops) != 0)
3261                         parseerror(parser, "internal error: leaked operands");
3262                     vec_push(localblock->exprs, (ast_expression*)sy.out[0].out);
3263                 }
3264                 vec_free(sy.out);
3265                 vec_free(sy.ops);
3266             }
3267         }
3268
3269 another:
3270         if (parser->tok == ',') {
3271             if (!parser_next(parser)) {
3272                 parseerror(parser, "expected another variable");
3273                 break;
3274             }
3275
3276             if (parser->tok != TOKEN_IDENT) {
3277                 parseerror(parser, "expected another variable");
3278                 break;
3279             }
3280             var = ast_value_copy(basetype);
3281             cleanvar = true;
3282             ast_value_set_name(var, parser_tokval(parser));
3283             if (!parser_next(parser)) {
3284                 parseerror(parser, "error parsing variable declaration");
3285                 break;
3286             }
3287             continue;
3288         }
3289
3290         if (parser->tok != ';') {
3291             parseerror(parser, "missing semicolon after variables");
3292             break;
3293         }
3294
3295         if (!parser_next(parser)) {
3296             parseerror(parser, "parse error after variable declaration");
3297             break;
3298         }
3299
3300         ast_delete(basetype);
3301         return true;
3302     }
3303
3304     if (cleanvar && var)
3305         ast_delete(var);
3306     ast_delete(basetype);
3307     return false;
3308
3309 cleanup:
3310     ast_delete(basetype);
3311     if (cleanvar && var)
3312         ast_delete(var);
3313     if (varent.name) mem_d(varent.name);
3314     if (ve[0].name)  mem_d(ve[0].name);
3315     if (ve[1].name)  mem_d(ve[1].name);
3316     if (ve[2].name)  mem_d(ve[2].name);
3317     if (ve[0].var)   mem_d(ve[0].var);
3318     if (ve[1].var)   mem_d(ve[1].var);
3319     if (ve[2].var)   mem_d(ve[2].var);
3320     return retval;
3321 }
3322
3323 static bool parser_global_statement(parser_t *parser)
3324 {
3325     if (parser->tok == TOKEN_TYPENAME || parser->tok == '.')
3326     {
3327         return parse_variable(parser, NULL, false);
3328     }
3329     else if (parser->tok == TOKEN_KEYWORD)
3330     {
3331         /* handle 'var' and 'const' */
3332         if (!strcmp(parser_tokval(parser), "var")) {
3333             if (!parser_next(parser)) {
3334                 parseerror(parser, "expected variable declaration after 'var'");
3335                 return false;
3336             }
3337             return parse_variable(parser, NULL, true);
3338         }
3339         return false;
3340     }
3341     else if (parser->tok == '$')
3342     {
3343         if (!parser_next(parser)) {
3344             parseerror(parser, "parse error");
3345             return false;
3346         }
3347     }
3348     else
3349     {
3350         parseerror(parser, "unexpected token: %s", parser->lex->tok.value);
3351         return false;
3352     }
3353     return true;
3354 }
3355
3356 static parser_t *parser;
3357
3358 bool parser_init()
3359 {
3360     size_t i;
3361     parser = (parser_t*)mem_a(sizeof(parser_t));
3362     if (!parser)
3363         return false;
3364
3365     memset(parser, 0, sizeof(*parser));
3366
3367     for (i = 0; i < operator_count; ++i) {
3368         if (operators[i].id == opid1('=')) {
3369             parser->assign_op = operators+i;
3370             break;
3371         }
3372     }
3373     if (!parser->assign_op) {
3374         printf("internal error: initializing parser: failed to find assign operator\n");
3375         mem_d(parser);
3376         return false;
3377     }
3378     return true;
3379 }
3380
3381 bool parser_compile()
3382 {
3383     /* initial lexer/parser state */
3384     parser->lex->flags.noops = true;
3385
3386     if (parser_next(parser))
3387     {
3388         while (parser->tok != TOKEN_EOF && parser->tok < TOKEN_ERROR)
3389         {
3390             if (!parser_global_statement(parser)) {
3391                 if (parser->tok == TOKEN_EOF)
3392                     parseerror(parser, "unexpected eof");
3393                 else if (!parser->errors)
3394                     parseerror(parser, "there have been errors, bailing out");
3395                 lex_close(parser->lex);
3396                 parser->lex = NULL;
3397                 return false;
3398             }
3399         }
3400     } else {
3401         parseerror(parser, "parse error");
3402         lex_close(parser->lex);
3403         parser->lex = NULL;
3404         return false;
3405     }
3406
3407     lex_close(parser->lex);
3408     parser->lex = NULL;
3409
3410     return !parser->errors;
3411 }
3412
3413 bool parser_compile_file(const char *filename)
3414 {
3415     parser->lex = lex_open(filename);
3416     if (!parser->lex) {
3417         con_out("failed to open file \"%s\"\n", filename);
3418         return false;
3419     }
3420     return parser_compile();
3421 }
3422
3423 bool parser_compile_string(const char *name, const char *str)
3424 {
3425     parser->lex = lex_open_string(str, strlen(str), name);
3426     if (!parser->lex) {
3427         con_out("failed to create lexer for string \"%s\"\n", name);
3428         return false;
3429     }
3430     return parser_compile();
3431 }
3432
3433 void parser_cleanup()
3434 {
3435     size_t i;
3436     for (i = 0; i < vec_size(parser->functions); ++i) {
3437         ast_delete(parser->functions[i]);
3438     }
3439     for (i = 0; i < vec_size(parser->imm_vector); ++i) {
3440         ast_delete(parser->imm_vector[i]);
3441     }
3442     for (i = 0; i < vec_size(parser->imm_string); ++i) {
3443         ast_delete(parser->imm_string[i]);
3444     }
3445     for (i = 0; i < vec_size(parser->imm_float); ++i) {
3446         ast_delete(parser->imm_float[i]);
3447     }
3448     for (i = 0; i < vec_size(parser->fields); ++i) {
3449         ast_delete(parser->fields[i].var);
3450         mem_d(parser->fields[i].name);
3451     }
3452     for (i = 0; i < vec_size(parser->globals); ++i) {
3453         ast_delete(parser->globals[i].var);
3454         mem_d(parser->globals[i].name);
3455     }
3456     vec_free(parser->functions);
3457     vec_free(parser->imm_vector);
3458     vec_free(parser->imm_string);
3459     vec_free(parser->imm_float);
3460     vec_free(parser->globals);
3461     vec_free(parser->fields);
3462     vec_free(parser->locals);
3463
3464     mem_d(parser);
3465 }
3466
3467 static uint16_t progdefs_crc_sum(uint16_t old, const char *str)
3468 {
3469     return util_crc16(old, str, strlen(str));
3470 }
3471
3472 static void progdefs_crc_file(const char *str)
3473 {
3474     /* write to progdefs.h here */
3475 }
3476
3477 static uint16_t progdefs_crc_both(uint16_t old, const char *str)
3478 {
3479     old = progdefs_crc_sum(old, str);
3480     progdefs_crc_file(str);
3481     return old;
3482 }
3483
3484 static void generate_checksum(parser_t *parser)
3485 {
3486     uint16_t crc = 0xFFFF;
3487     size_t i;
3488
3489         crc = progdefs_crc_both(crc, "\n/* file generated by qcc, do not modify */\n\ntypedef struct\n{");
3490         crc = progdefs_crc_sum(crc, "\tint\tpad[28];\n");
3491         /*
3492         progdefs_crc_file("\tint\tpad;\n");
3493         progdefs_crc_file("\tint\tofs_return[3];\n");
3494         progdefs_crc_file("\tint\tofs_parm0[3];\n");
3495         progdefs_crc_file("\tint\tofs_parm1[3];\n");
3496         progdefs_crc_file("\tint\tofs_parm2[3];\n");
3497         progdefs_crc_file("\tint\tofs_parm3[3];\n");
3498         progdefs_crc_file("\tint\tofs_parm4[3];\n");
3499         progdefs_crc_file("\tint\tofs_parm5[3];\n");
3500         progdefs_crc_file("\tint\tofs_parm6[3];\n");
3501         progdefs_crc_file("\tint\tofs_parm7[3];\n");
3502         */
3503         for (i = 0; i < parser->crc_globals; ++i) {
3504             if (!ast_istype(parser->globals[i].var, ast_value))
3505                 continue;
3506             switch (parser->globals[i].var->expression.vtype) {
3507                 case TYPE_FLOAT:    crc = progdefs_crc_both(crc, "\tfloat\t"); break;
3508                 case TYPE_VECTOR:   crc = progdefs_crc_both(crc, "\tvec3_t\t"); break;
3509                 case TYPE_STRING:   crc = progdefs_crc_both(crc, "\tstring_t\t"); break;
3510                 case TYPE_FUNCTION: crc = progdefs_crc_both(crc, "\tfunc_t\t"); break;
3511                 default:
3512                     crc = progdefs_crc_both(crc, "\tint\t");
3513                     break;
3514             }
3515             crc = progdefs_crc_both(crc, parser->globals[i].name);
3516             crc = progdefs_crc_both(crc, ";\n");
3517         }
3518         crc = progdefs_crc_both(crc, "} globalvars_t;\n\ntypedef struct\n{\n");
3519         for (i = 0; i < parser->crc_fields; ++i) {
3520             if (!ast_istype(parser->fields[i].var, ast_value))
3521                 continue;
3522             switch (parser->fields[i].var->expression.next->expression.vtype) {
3523                 case TYPE_FLOAT:    crc = progdefs_crc_both(crc, "\tfloat\t"); break;
3524                 case TYPE_VECTOR:   crc = progdefs_crc_both(crc, "\tvec3_t\t"); break;
3525                 case TYPE_STRING:   crc = progdefs_crc_both(crc, "\tstring_t\t"); break;
3526                 case TYPE_FUNCTION: crc = progdefs_crc_both(crc, "\tfunc_t\t"); break;
3527                 default:
3528                     crc = progdefs_crc_both(crc, "\tint\t");
3529                     break;
3530             }
3531             crc = progdefs_crc_both(crc, parser->fields[i].name);
3532             crc = progdefs_crc_both(crc, ";\n");
3533         }
3534         crc = progdefs_crc_both(crc, "} entvars_t;\n\n");
3535
3536         code_crc = crc;
3537 }
3538
3539 bool parser_finish(const char *output)
3540 {
3541     size_t i;
3542     ir_builder *ir;
3543     bool retval = true;
3544
3545     if (!parser->errors)
3546     {
3547         ir = ir_builder_new("gmqcc_out");
3548         if (!ir) {
3549             con_out("failed to allocate builder\n");
3550             return false;
3551         }
3552
3553         for (i = 0; i < vec_size(parser->fields); ++i) {
3554             ast_value *field;
3555             bool isconst;
3556             if (!ast_istype(parser->fields[i].var, ast_value))
3557                 continue;
3558             field = (ast_value*)parser->fields[i].var;
3559             isconst = field->isconst;
3560             field->isconst = false;
3561             if (!ast_global_codegen((ast_value*)field, ir, true)) {
3562                 con_out("failed to generate field %s\n", field->name);
3563                 ir_builder_delete(ir);
3564                 return false;
3565             }
3566             if (isconst) {
3567                 ir_value *ifld;
3568                 ast_expression *subtype;
3569                 field->isconst = true;
3570                 subtype = field->expression.next;
3571                 ifld = ir_builder_create_field(ir, field->name, subtype->expression.vtype);
3572                 if (subtype->expression.vtype == TYPE_FIELD)
3573                     ifld->fieldtype = subtype->expression.next->expression.vtype;
3574                 else if (subtype->expression.vtype == TYPE_FUNCTION)
3575                     ifld->outtype = subtype->expression.next->expression.vtype;
3576                 (void)!ir_value_set_field(field->ir_v, ifld);
3577             }
3578         }
3579         for (i = 0; i < vec_size(parser->globals); ++i) {
3580             ast_value *asvalue;
3581             if (!ast_istype(parser->globals[i].var, ast_value))
3582                 continue;
3583             asvalue = (ast_value*)(parser->globals[i].var);
3584             if (!asvalue->uses && !asvalue->isconst && asvalue->expression.vtype != TYPE_FUNCTION) {
3585                 if (strcmp(asvalue->name, "end_sys_globals") &&
3586                     strcmp(asvalue->name, "end_sys_fields"))
3587                 {
3588                     retval = retval && !genwarning(ast_ctx(asvalue), WARN_UNUSED_VARIABLE,
3589                                                    "unused global: `%s`", asvalue->name);
3590                 }
3591             }
3592             if (!ast_global_codegen(asvalue, ir, false)) {
3593                 con_out("failed to generate global %s\n", parser->globals[i].name);
3594                 ir_builder_delete(ir);
3595                 return false;
3596             }
3597         }
3598         for (i = 0; i < vec_size(parser->imm_float); ++i) {
3599             if (!ast_global_codegen(parser->imm_float[i], ir, false)) {
3600                 con_out("failed to generate global %s\n", parser->imm_float[i]->name);
3601                 ir_builder_delete(ir);
3602                 return false;
3603             }
3604         }
3605         for (i = 0; i < vec_size(parser->imm_string); ++i) {
3606             if (!ast_global_codegen(parser->imm_string[i], ir, false)) {
3607                 con_out("failed to generate global %s\n", parser->imm_string[i]->name);
3608                 ir_builder_delete(ir);
3609                 return false;
3610             }
3611         }
3612         for (i = 0; i < vec_size(parser->imm_vector); ++i) {
3613             if (!ast_global_codegen(parser->imm_vector[i], ir, false)) {
3614                 con_out("failed to generate global %s\n", parser->imm_vector[i]->name);
3615                 ir_builder_delete(ir);
3616                 return false;
3617             }
3618         }
3619         for (i = 0; i < vec_size(parser->globals); ++i) {
3620             ast_value *asvalue;
3621             if (!ast_istype(parser->globals[i].var, ast_value))
3622                 continue;
3623             asvalue = (ast_value*)(parser->globals[i].var);
3624             if (asvalue->setter) {
3625                 if (!ast_global_codegen(asvalue->setter, ir, false) ||
3626                     !ast_function_codegen(asvalue->setter->constval.vfunc, ir) ||
3627                     !ir_function_finalize(asvalue->setter->constval.vfunc->ir_func))
3628                 {
3629                     printf("failed to generate setter for %s\n", parser->globals[i].name);
3630                     ir_builder_delete(ir);
3631                     return false;
3632                 }
3633             }
3634             if (asvalue->getter) {
3635                 if (!ast_global_codegen(asvalue->getter, ir, false) ||
3636                     !ast_function_codegen(asvalue->getter->constval.vfunc, ir) ||
3637                     !ir_function_finalize(asvalue->getter->constval.vfunc->ir_func))
3638                 {
3639                     printf("failed to generate getter for %s\n", parser->globals[i].name);
3640                     ir_builder_delete(ir);
3641                     return false;
3642                 }
3643             }
3644         }
3645         for (i = 0; i < vec_size(parser->fields); ++i) {
3646             ast_value *asvalue;
3647             asvalue = (ast_value*)(parser->fields[i].var->expression.next);
3648
3649             if (!ast_istype((ast_expression*)asvalue, ast_value))
3650                 continue;
3651             if (asvalue->expression.vtype != TYPE_ARRAY)
3652                 continue;
3653             if (asvalue->setter) {
3654                 if (!ast_global_codegen(asvalue->setter, ir, false) ||
3655                     !ast_function_codegen(asvalue->setter->constval.vfunc, ir) ||
3656                     !ir_function_finalize(asvalue->setter->constval.vfunc->ir_func))
3657                 {
3658                     printf("failed to generate setter for %s\n", parser->fields[i].name);
3659                     ir_builder_delete(ir);
3660                     return false;
3661                 }
3662             }
3663             if (asvalue->getter) {
3664                 if (!ast_global_codegen(asvalue->getter, ir, false) ||
3665                     !ast_function_codegen(asvalue->getter->constval.vfunc, ir) ||
3666                     !ir_function_finalize(asvalue->getter->constval.vfunc->ir_func))
3667                 {
3668                     printf("failed to generate getter for %s\n", parser->fields[i].name);
3669                     ir_builder_delete(ir);
3670                     return false;
3671                 }
3672             }
3673         }
3674         for (i = 0; i < vec_size(parser->functions); ++i) {
3675             if (!ast_function_codegen(parser->functions[i], ir)) {
3676                 con_out("failed to generate function %s\n", parser->functions[i]->name);
3677                 ir_builder_delete(ir);
3678                 return false;
3679             }
3680             if (!ir_function_finalize(parser->functions[i]->ir_func)) {
3681                 con_out("failed to finalize function %s\n", parser->functions[i]->name);
3682                 ir_builder_delete(ir);
3683                 return false;
3684             }
3685         }
3686
3687         if (retval) {
3688             if (opts_dump)
3689                 ir_builder_dump(ir, con_out);
3690
3691             generate_checksum(parser);
3692
3693             if (!ir_builder_generate(ir, output)) {
3694                 con_out("*** failed to generate output file\n");
3695                 ir_builder_delete(ir);
3696                 return false;
3697             }
3698         }
3699
3700         ir_builder_delete(ir);
3701         return retval;
3702     }
3703
3704     con_out("*** there were compile errors\n");
3705     return false;
3706 }