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