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