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