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