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