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