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