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