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