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