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