]> git.xonotic.org Git - xonotic/gmqcc.git/blob - parser.c
preprocessing flag for the lexer
[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                 ast_expression *field = ((ast_entfield*)exprs[0])->field;
869                 assignop = type_storep_instr[exprs[0]->expression.vtype];
870                 if (!ast_compare_type(field->expression.next, exprs[1])) {
871                     char ty1[1024];
872                     char ty2[1024];
873                     ast_type_to_string(field->expression.next, ty1, sizeof(ty1));
874                     ast_type_to_string(exprs[1], ty2, sizeof(ty2));
875                     if (opts_standard == COMPILER_QCC &&
876                         field->expression.next->expression.vtype == TYPE_FUNCTION &&
877                         exprs[1]->expression.vtype == TYPE_FUNCTION)
878                     {
879                         if (parsewarning(parser, WARN_ASSIGN_FUNCTION_TYPES,
880                                          "invalid types in assignment: cannot assign %s to %s", ty2, ty1))
881                         {
882                             parser->errors++;
883                         }
884                     }
885                     else
886                         parseerror(parser, "invalid types in assignment: cannot assign %s to %s", ty2, ty1);
887                 }
888             }
889             else
890             {
891                 assignop = type_store_instr[exprs[0]->expression.vtype];
892                 if (!ast_compare_type(exprs[0], exprs[1])) {
893                     char ty1[1024];
894                     char ty2[1024];
895                     ast_type_to_string(exprs[0], ty1, sizeof(ty1));
896                     ast_type_to_string(exprs[1], ty2, sizeof(ty2));
897                     if (opts_standard == COMPILER_QCC &&
898                         exprs[0]->expression.vtype == TYPE_FUNCTION &&
899                         exprs[1]->expression.vtype == TYPE_FUNCTION)
900                     {
901                         if (parsewarning(parser, WARN_ASSIGN_FUNCTION_TYPES,
902                                          "invalid types in assignment: cannot assign %s to %s", ty2, ty1))
903                         {
904                             parser->errors++;
905                         }
906                     }
907                     else
908                         parseerror(parser, "invalid types in assignment: cannot assign %s to %s", ty2, ty1);
909                 }
910             }
911             out = (ast_expression*)ast_store_new(ctx, assignop, exprs[0], exprs[1]);
912             break;
913         case opid2('+','='):
914         case opid2('-','='):
915             if (exprs[0]->expression.vtype != exprs[1]->expression.vtype ||
916                 (exprs[0]->expression.vtype != TYPE_VECTOR && exprs[0]->expression.vtype != TYPE_FLOAT) )
917             {
918                 parseerror(parser, "invalid types used in expression: cannot add or subtract type %s and %s",
919                            type_name[exprs[0]->expression.vtype],
920                            type_name[exprs[1]->expression.vtype]);
921                 return false;
922             }
923             if (ast_istype(exprs[0], ast_entfield))
924                 assignop = type_storep_instr[exprs[0]->expression.vtype];
925             else
926                 assignop = type_store_instr[exprs[0]->expression.vtype];
927             switch (exprs[0]->expression.vtype) {
928                 case TYPE_FLOAT:
929                     out = (ast_expression*)ast_binstore_new(ctx, assignop,
930                                                             (op->id == opid2('+','=') ? INSTR_ADD_F : INSTR_SUB_F),
931                                                             exprs[0], exprs[1]);
932                     break;
933                 case TYPE_VECTOR:
934                     out = (ast_expression*)ast_binstore_new(ctx, assignop,
935                                                             (op->id == opid2('+','=') ? INSTR_ADD_V : INSTR_SUB_V),
936                                                             exprs[0], exprs[1]);
937                     break;
938                 default:
939                     parseerror(parser, "invalid types used in expression: cannot add or subtract type %s and %s",
940                                type_name[exprs[0]->expression.vtype],
941                                type_name[exprs[1]->expression.vtype]);
942                     return false;
943             };
944             break;
945     }
946 #undef NotSameType
947
948     if (!out) {
949         parseerror(parser, "failed to apply operand %s", op->op);
950         return false;
951     }
952
953     DEBUGSHUNTDO(printf("applied %s\n", op->op));
954     sy->out[sy->out_count++] = syexp(ctx, out);
955     return true;
956 }
957
958 static bool parser_close_call(parser_t *parser, shunt *sy)
959 {
960     /* was a function call */
961     ast_expression *fun;
962     ast_call       *call;
963
964     size_t          fid;
965     size_t          paramcount;
966
967     sy->ops_count--;
968     fid = sy->ops[sy->ops_count].off;
969
970     /* out[fid] is the function
971      * everything above is parameters...
972      * 0 params = nothing
973      * 1 params = ast_expression
974      * more = ast_block
975      */
976
977     if (sy->out_count < 1 || sy->out_count <= fid) {
978         parseerror(parser, "internal error: function call needs function and parameter list...");
979         return false;
980     }
981
982     fun = sy->out[fid].out;
983
984     call = ast_call_new(sy->ops[sy->ops_count].ctx, fun);
985     if (!call) {
986         parseerror(parser, "out of memory");
987         return false;
988     }
989
990     if (fid+1 == sy->out_count) {
991         /* no arguments */
992         paramcount = 0;
993     } else if (fid+2 == sy->out_count) {
994         ast_block *params;
995         sy->out_count--;
996         params = sy->out[sy->out_count].block;
997         if (!params) {
998             /* 1 param */
999             paramcount = 1;
1000             if (!ast_call_params_add(call, sy->out[sy->out_count].out)) {
1001                 ast_delete(sy->out[sy->out_count].out);
1002                 parseerror(parser, "out of memory");
1003                 return false;
1004             }
1005         } else {
1006             paramcount = params->exprs_count;
1007             MEM_VECTOR_MOVE(params, exprs, call, params);
1008             ast_delete(params);
1009         }
1010         if (!ast_call_check_types(call))
1011             parser->errors++;
1012     } else {
1013         parseerror(parser, "invalid function call");
1014         return false;
1015     }
1016
1017     /* overwrite fid, the function, with a call */
1018     sy->out[fid] = syexp(call->expression.node.context, (ast_expression*)call);
1019
1020     if (fun->expression.vtype != TYPE_FUNCTION) {
1021         parseerror(parser, "not a function (%s)", type_name[fun->expression.vtype]);
1022         return false;
1023     }
1024
1025     if (!fun->expression.next) {
1026         parseerror(parser, "could not determine function return type");
1027         return false;
1028     } else {
1029         if (fun->expression.params_count != paramcount &&
1030             !(fun->expression.variadic &&
1031               fun->expression.params_count < paramcount))
1032         {
1033             ast_value *fval;
1034             const char *fewmany = (fun->expression.params_count > paramcount) ? "few" : "many";
1035
1036             fval = (ast_istype(fun, ast_value) ? ((ast_value*)fun) : NULL);
1037             if (opts_standard == COMPILER_GMQCC)
1038             {
1039                 if (fval)
1040                     parseerror(parser, "too %s parameters for call to %s: expected %i, got %i\n"
1041                                " -> `%s` has been declared here: %s:%i",
1042                                fewmany, fval->name, (int)fun->expression.params_count, (int)paramcount,
1043                                fval->name, ast_ctx(fun).file, (int)ast_ctx(fun).line);
1044                 else
1045                     parseerror(parser, "too %s parameters for function call: expected %i, got %i\n"
1046                                " -> `%s` has been declared here: %s:%i",
1047                                fewmany, fval->name, (int)fun->expression.params_count, (int)paramcount,
1048                                fval->name, ast_ctx(fun).file, (int)ast_ctx(fun).line);
1049                 return false;
1050             }
1051             else
1052             {
1053                 if (fval)
1054                     return !parsewarning(parser, WARN_TOO_FEW_PARAMETERS,
1055                                          "too %s parameters for call to %s: expected %i, got %i\n"
1056                                          " -> `%s` has been declared here: %s:%i",
1057                                          fewmany, fval->name, (int)fun->expression.params_count, (int)paramcount,
1058                                          fval->name, ast_ctx(fun).file, (int)ast_ctx(fun).line);
1059                 else
1060                     return !parsewarning(parser, WARN_TOO_FEW_PARAMETERS,
1061                                          "too %s parameters for function call: expected %i, got %i\n"
1062                                          " -> `%s` has been declared here: %s:%i",
1063                                          fewmany, fval->name, (int)fun->expression.params_count, (int)paramcount,
1064                                          fval->name, ast_ctx(fun).file, (int)ast_ctx(fun).line);
1065             }
1066         }
1067     }
1068
1069     return true;
1070 }
1071
1072 static bool parser_close_paren(parser_t *parser, shunt *sy, bool functions_only)
1073 {
1074     if (!sy->ops_count) {
1075         parseerror(parser, "unmatched closing paren");
1076         return false;
1077     }
1078     /* this would for bit a + (x) because there are no operators inside (x)
1079     if (sy->ops[sy->ops_count-1].paren == 1) {
1080         parseerror(parser, "empty parenthesis expression");
1081         return false;
1082     }
1083     */
1084     while (sy->ops_count) {
1085         if (sy->ops[sy->ops_count-1].paren == 'f') {
1086             if (!parser_close_call(parser, sy))
1087                 return false;
1088             break;
1089         }
1090         if (sy->ops[sy->ops_count-1].paren == 1) {
1091             sy->ops_count--;
1092             return !functions_only;
1093         }
1094         if (!parser_sy_pop(parser, sy))
1095             return false;
1096     }
1097     return true;
1098 }
1099
1100 static void parser_reclassify_token(parser_t *parser)
1101 {
1102     size_t i;
1103     for (i = 0; i < operator_count; ++i) {
1104         if (!strcmp(parser_tokval(parser), operators[i].op)) {
1105             parser->tok = TOKEN_OPERATOR;
1106             return;
1107         }
1108     }
1109 }
1110
1111 static ast_expression* parse_expression_leave(parser_t *parser, bool stopatcomma)
1112 {
1113     ast_expression *expr = NULL;
1114     shunt sy;
1115     bool wantop = false;
1116     bool gotmemberof = false;
1117
1118     /* count the parens because an if starts with one, so the
1119      * end of a condition is an unmatched closing paren
1120      */
1121     int parens = 0;
1122
1123     MEM_VECTOR_INIT(&sy, out);
1124     MEM_VECTOR_INIT(&sy, ops);
1125
1126     parser->lex->flags.noops = false;
1127
1128     parser_reclassify_token(parser);
1129
1130     while (true)
1131     {
1132         if (gotmemberof)
1133             gotmemberof = false;
1134         else
1135             parser->memberof = 0;
1136
1137         if (parser->tok == TOKEN_IDENT)
1138         {
1139             ast_expression *var;
1140             if (wantop) {
1141                 parseerror(parser, "expected operator or end of statement");
1142                 goto onerr;
1143             }
1144             wantop = true;
1145             /* variable */
1146             if (opts_standard == COMPILER_GMQCC)
1147             {
1148                 if (parser->memberof == TYPE_ENTITY) {
1149                     /* still get vars first since there could be a fieldpointer */
1150                     var = parser_find_var(parser, parser_tokval(parser));
1151                     if (!var)
1152                         var = parser_find_field(parser, parser_tokval(parser));
1153                 }
1154                 else if (parser->memberof == TYPE_VECTOR)
1155                 {
1156                     parseerror(parser, "TODO: implement effective vector member access");
1157                     goto onerr;
1158                 }
1159                 else if (parser->memberof) {
1160                     parseerror(parser, "namespace for member not found");
1161                     goto onerr;
1162                 }
1163                 else
1164                     var = parser_find_var(parser, parser_tokval(parser));
1165             } else {
1166                 var = parser_find_var(parser, parser_tokval(parser));
1167                 if (!var)
1168                     var = parser_find_field(parser, parser_tokval(parser));
1169             }
1170             if (!var) {
1171                 parseerror(parser, "unexpected ident: %s", parser_tokval(parser));
1172                 goto onerr;
1173             }
1174             if (ast_istype(var, ast_value))
1175                 ((ast_value*)var)->uses++;
1176             if (!shunt_out_add(&sy, syexp(parser_ctx(parser), var))) {
1177                 parseerror(parser, "out of memory");
1178                 goto onerr;
1179             }
1180             DEBUGSHUNTDO(printf("push %s\n", parser_tokval(parser)));
1181         }
1182         else if (parser->tok == TOKEN_FLOATCONST) {
1183             ast_value *val;
1184             if (wantop) {
1185                 parseerror(parser, "expected operator or end of statement, got constant");
1186                 goto onerr;
1187             }
1188             wantop = true;
1189             val = parser_const_float(parser, (parser_token(parser)->constval.f));
1190             if (!val)
1191                 return false;
1192             if (!shunt_out_add(&sy, syexp(parser_ctx(parser), (ast_expression*)val))) {
1193                 parseerror(parser, "out of memory");
1194                 goto onerr;
1195             }
1196             DEBUGSHUNTDO(printf("push %g\n", parser_token(parser)->constval.f));
1197         }
1198         else if (parser->tok == TOKEN_INTCONST) {
1199             ast_value *val;
1200             if (wantop) {
1201                 parseerror(parser, "expected operator or end of statement, got constant");
1202                 goto onerr;
1203             }
1204             wantop = true;
1205             val = parser_const_float(parser, (double)(parser_token(parser)->constval.i));
1206             if (!val)
1207                 return false;
1208             if (!shunt_out_add(&sy, syexp(parser_ctx(parser), (ast_expression*)val))) {
1209                 parseerror(parser, "out of memory");
1210                 goto onerr;
1211             }
1212             DEBUGSHUNTDO(printf("push %i\n", parser_token(parser)->constval.i));
1213         }
1214         else if (parser->tok == TOKEN_STRINGCONST) {
1215             ast_value *val;
1216             if (wantop) {
1217                 parseerror(parser, "expected operator or end of statement, got constant");
1218                 goto onerr;
1219             }
1220             wantop = true;
1221             val = parser_const_string(parser, parser_tokval(parser));
1222             if (!val)
1223                 return false;
1224             if (!shunt_out_add(&sy, syexp(parser_ctx(parser), (ast_expression*)val))) {
1225                 parseerror(parser, "out of memory");
1226                 goto onerr;
1227             }
1228             DEBUGSHUNTDO(printf("push string\n"));
1229         }
1230         else if (parser->tok == TOKEN_VECTORCONST) {
1231             ast_value *val;
1232             if (wantop) {
1233                 parseerror(parser, "expected operator or end of statement, got constant");
1234                 goto onerr;
1235             }
1236             wantop = true;
1237             val = parser_const_vector(parser, parser_token(parser)->constval.v);
1238             if (!val)
1239                 return false;
1240             if (!shunt_out_add(&sy, syexp(parser_ctx(parser), (ast_expression*)val))) {
1241                 parseerror(parser, "out of memory");
1242                 goto onerr;
1243             }
1244             DEBUGSHUNTDO(printf("push '%g %g %g'\n",
1245                                 parser_token(parser)->constval.v.x,
1246                                 parser_token(parser)->constval.v.y,
1247                                 parser_token(parser)->constval.v.z));
1248         }
1249         else if (parser->tok == '(') {
1250             parseerror(parser, "internal error: '(' should be classified as operator");
1251             goto onerr;
1252         }
1253         else if (parser->tok == ')') {
1254             if (wantop) {
1255                 DEBUGSHUNTDO(printf("do[op] )\n"));
1256                 --parens;
1257                 if (parens < 0)
1258                     break;
1259                 /* we do expect an operator next */
1260                 /* closing an opening paren */
1261                 if (!parser_close_paren(parser, &sy, false))
1262                     goto onerr;
1263             } else {
1264                 DEBUGSHUNTDO(printf("do[nop] )\n"));
1265                 --parens;
1266                 if (parens < 0)
1267                     break;
1268                 /* allowed for function calls */
1269                 if (!parser_close_paren(parser, &sy, true))
1270                     goto onerr;
1271             }
1272             wantop = true;
1273         }
1274         else if (parser->tok != TOKEN_OPERATOR) {
1275             if (wantop) {
1276                 parseerror(parser, "expected operator or end of statement");
1277                 goto onerr;
1278             }
1279             break;
1280         }
1281         else
1282         {
1283             /* classify the operator */
1284             /* TODO: suffix operators */
1285             const oper_info *op;
1286             const oper_info *olast = NULL;
1287             size_t o;
1288             for (o = 0; o < operator_count; ++o) {
1289                 if ((!(operators[o].flags & OP_PREFIX) == wantop) &&
1290                     !(operators[o].flags & OP_SUFFIX) && /* remove this */
1291                     !strcmp(parser_tokval(parser), operators[o].op))
1292                 {
1293                     break;
1294                 }
1295             }
1296             if (o == operator_count) {
1297                 /* no operator found... must be the end of the statement */
1298                 break;
1299             }
1300             /* found an operator */
1301             op = &operators[o];
1302
1303             /* when declaring variables, a comma starts a new variable */
1304             if (op->id == opid1(',') && !parens && stopatcomma) {
1305                 /* fixup the token */
1306                 parser->tok = ',';
1307                 break;
1308             }
1309
1310             if (sy.ops_count && !sy.ops[sy.ops_count-1].paren)
1311                 olast = &operators[sy.ops[sy.ops_count-1].etype-1];
1312
1313             while (olast && (
1314                     (op->prec < olast->prec) ||
1315                     (op->assoc == ASSOC_LEFT && op->prec <= olast->prec) ) )
1316             {
1317                 if (!parser_sy_pop(parser, &sy))
1318                     goto onerr;
1319                 if (sy.ops_count && !sy.ops[sy.ops_count-1].paren)
1320                     olast = &operators[sy.ops[sy.ops_count-1].etype-1];
1321                 else
1322                     olast = NULL;
1323             }
1324
1325             if (op->id == opid1('.') && opts_standard == COMPILER_GMQCC) {
1326                 /* for gmqcc standard: open up the namespace of the previous type */
1327                 ast_expression *prevex = sy.out[sy.out_count-1].out;
1328                 if (!prevex) {
1329                     parseerror(parser, "unexpected member operator");
1330                     goto onerr;
1331                 }
1332                 if (prevex->expression.vtype == TYPE_ENTITY)
1333                     parser->memberof = TYPE_ENTITY;
1334                 else if (prevex->expression.vtype == TYPE_VECTOR)
1335                     parser->memberof = TYPE_VECTOR;
1336                 else {
1337                     parseerror(parser, "type error: type has no members");
1338                     goto onerr;
1339                 }
1340                 gotmemberof = true;
1341             }
1342
1343             if (op->id == opid1('(')) {
1344                 if (wantop) {
1345                     DEBUGSHUNTDO(printf("push [op] (\n"));
1346                     ++parens;
1347                     /* we expected an operator, this is the function-call operator */
1348                     if (!shunt_ops_add(&sy, syparen(parser_ctx(parser), 'f', sy.out_count-1))) {
1349                         parseerror(parser, "out of memory");
1350                         goto onerr;
1351                     }
1352                 } else {
1353                     ++parens;
1354                     if (!shunt_ops_add(&sy, syparen(parser_ctx(parser), 1, 0))) {
1355                         parseerror(parser, "out of memory");
1356                         goto onerr;
1357                     }
1358                     DEBUGSHUNTDO(printf("push [nop] (\n"));
1359                 }
1360                 wantop = false;
1361             } else {
1362                 DEBUGSHUNTDO(printf("push operator %s\n", op->op));
1363                 if (!shunt_ops_add(&sy, syop(parser_ctx(parser), op)))
1364                     goto onerr;
1365                 wantop = false;
1366             }
1367         }
1368         if (!parser_next(parser)) {
1369             goto onerr;
1370         }
1371         if (parser->tok == ';' || parser->tok == ']') {
1372             break;
1373         }
1374     }
1375
1376     while (sy.ops_count) {
1377         if (!parser_sy_pop(parser, &sy))
1378             goto onerr;
1379     }
1380
1381     parser->lex->flags.noops = true;
1382     if (!sy.out_count) {
1383         parseerror(parser, "empty expression");
1384         expr = NULL;
1385     } else
1386         expr = sy.out[0].out;
1387     MEM_VECTOR_CLEAR(&sy, out);
1388     MEM_VECTOR_CLEAR(&sy, ops);
1389     DEBUGSHUNTDO(printf("shunt done\n"));
1390     return expr;
1391
1392 onerr:
1393     parser->lex->flags.noops = true;
1394     MEM_VECTOR_CLEAR(&sy, out);
1395     MEM_VECTOR_CLEAR(&sy, ops);
1396     return NULL;
1397 }
1398
1399 static ast_expression* parse_expression(parser_t *parser, bool stopatcomma)
1400 {
1401     ast_expression *e = parse_expression_leave(parser, stopatcomma);
1402     if (!e)
1403         return NULL;
1404     if (!parser_next(parser)) {
1405         ast_delete(e);
1406         return NULL;
1407     }
1408     return e;
1409 }
1410
1411 static bool parse_if(parser_t *parser, ast_block *block, ast_expression **out)
1412 {
1413     ast_ifthen *ifthen;
1414     ast_expression *cond, *ontrue, *onfalse = NULL;
1415
1416     lex_ctx ctx = parser_ctx(parser);
1417
1418     /* skip the 'if' and check for opening paren */
1419     if (!parser_next(parser) || parser->tok != '(') {
1420         parseerror(parser, "expected 'if' condition in parenthesis");
1421         return false;
1422     }
1423     /* parse into the expression */
1424     if (!parser_next(parser)) {
1425         parseerror(parser, "expected 'if' condition after opening paren");
1426         return false;
1427     }
1428     /* parse the condition */
1429     cond = parse_expression_leave(parser, false);
1430     if (!cond)
1431         return false;
1432     /* closing paren */
1433     if (parser->tok != ')') {
1434         parseerror(parser, "expected closing paren after 'if' condition");
1435         ast_delete(cond);
1436         return false;
1437     }
1438     /* parse into the 'then' branch */
1439     if (!parser_next(parser)) {
1440         parseerror(parser, "expected statement for on-true branch of 'if'");
1441         ast_delete(cond);
1442         return false;
1443     }
1444     ontrue = parse_statement_or_block(parser);
1445     if (!ontrue) {
1446         ast_delete(cond);
1447         return false;
1448     }
1449     /* check for an else */
1450     if (!strcmp(parser_tokval(parser), "else")) {
1451         /* parse into the 'else' branch */
1452         if (!parser_next(parser)) {
1453             parseerror(parser, "expected on-false branch after 'else'");
1454             ast_delete(ontrue);
1455             ast_delete(cond);
1456             return false;
1457         }
1458         onfalse = parse_statement_or_block(parser);
1459         if (!onfalse) {
1460             ast_delete(ontrue);
1461             ast_delete(cond);
1462             return false;
1463         }
1464     }
1465
1466     ifthen = ast_ifthen_new(ctx, cond, ontrue, onfalse);
1467     *out = (ast_expression*)ifthen;
1468     return true;
1469 }
1470
1471 static bool parse_while(parser_t *parser, ast_block *block, ast_expression **out)
1472 {
1473     ast_loop *aloop;
1474     ast_expression *cond, *ontrue;
1475
1476     lex_ctx ctx = parser_ctx(parser);
1477
1478     /* skip the 'while' and check for opening paren */
1479     if (!parser_next(parser) || parser->tok != '(') {
1480         parseerror(parser, "expected 'while' condition in parenthesis");
1481         return false;
1482     }
1483     /* parse into the expression */
1484     if (!parser_next(parser)) {
1485         parseerror(parser, "expected 'while' condition after opening paren");
1486         return false;
1487     }
1488     /* parse the condition */
1489     cond = parse_expression_leave(parser, false);
1490     if (!cond)
1491         return false;
1492     /* closing paren */
1493     if (parser->tok != ')') {
1494         parseerror(parser, "expected closing paren after 'while' condition");
1495         ast_delete(cond);
1496         return false;
1497     }
1498     /* parse into the 'then' branch */
1499     if (!parser_next(parser)) {
1500         parseerror(parser, "expected while-loop body");
1501         ast_delete(cond);
1502         return false;
1503     }
1504     ontrue = parse_statement_or_block(parser);
1505     if (!ontrue) {
1506         ast_delete(cond);
1507         return false;
1508     }
1509
1510     aloop = ast_loop_new(ctx, NULL, cond, NULL, NULL, ontrue);
1511     *out = (ast_expression*)aloop;
1512     return true;
1513 }
1514
1515 static bool parse_dowhile(parser_t *parser, ast_block *block, ast_expression **out)
1516 {
1517     ast_loop *aloop;
1518     ast_expression *cond, *ontrue;
1519
1520     lex_ctx ctx = parser_ctx(parser);
1521
1522     /* skip the 'do' and get the body */
1523     if (!parser_next(parser)) {
1524         parseerror(parser, "expected loop body");
1525         return false;
1526     }
1527     ontrue = parse_statement_or_block(parser);
1528     if (!ontrue)
1529         return false;
1530
1531     /* expect the "while" */
1532     if (parser->tok != TOKEN_KEYWORD ||
1533         strcmp(parser_tokval(parser), "while"))
1534     {
1535         parseerror(parser, "expected 'while' and condition");
1536         ast_delete(ontrue);
1537         return false;
1538     }
1539
1540     /* skip the 'while' and check for opening paren */
1541     if (!parser_next(parser) || parser->tok != '(') {
1542         parseerror(parser, "expected 'while' condition in parenthesis");
1543         ast_delete(ontrue);
1544         return false;
1545     }
1546     /* parse into the expression */
1547     if (!parser_next(parser)) {
1548         parseerror(parser, "expected 'while' condition after opening paren");
1549         ast_delete(ontrue);
1550         return false;
1551     }
1552     /* parse the condition */
1553     cond = parse_expression_leave(parser, false);
1554     if (!cond)
1555         return false;
1556     /* closing paren */
1557     if (parser->tok != ')') {
1558         parseerror(parser, "expected closing paren after 'while' condition");
1559         ast_delete(ontrue);
1560         ast_delete(cond);
1561         return false;
1562     }
1563     /* parse on */
1564     if (!parser_next(parser) || parser->tok != ';') {
1565         parseerror(parser, "expected semicolon after condition");
1566         ast_delete(ontrue);
1567         ast_delete(cond);
1568         return false;
1569     }
1570
1571     if (!parser_next(parser)) {
1572         parseerror(parser, "parse error");
1573         ast_delete(ontrue);
1574         ast_delete(cond);
1575         return false;
1576     }
1577
1578     aloop = ast_loop_new(ctx, NULL, NULL, cond, NULL, ontrue);
1579     *out = (ast_expression*)aloop;
1580     return true;
1581 }
1582
1583 static bool parse_for(parser_t *parser, ast_block *block, ast_expression **out)
1584 {
1585     ast_loop *aloop;
1586     ast_expression *initexpr, *cond, *increment, *ontrue;
1587     size_t oldblocklocal;
1588     bool   retval = true;
1589
1590     lex_ctx ctx = parser_ctx(parser);
1591
1592     oldblocklocal = parser->blocklocal;
1593     parser->blocklocal = parser->locals_count;
1594
1595     initexpr  = NULL;
1596     cond      = NULL;
1597     increment = NULL;
1598     ontrue    = NULL;
1599
1600     /* skip the 'while' and check for opening paren */
1601     if (!parser_next(parser) || parser->tok != '(') {
1602         parseerror(parser, "expected 'for' expressions in parenthesis");
1603         goto onerr;
1604     }
1605     /* parse into the expression */
1606     if (!parser_next(parser)) {
1607         parseerror(parser, "expected 'for' initializer after opening paren");
1608         goto onerr;
1609     }
1610
1611     if (parser->tok == TOKEN_TYPENAME) {
1612         if (opts_standard != COMPILER_GMQCC) {
1613             if (parsewarning(parser, WARN_EXTENSIONS,
1614                              "current standard does not allow variable declarations in for-loop initializers"))
1615                 goto onerr;
1616         }
1617
1618         parseerror(parser, "TODO: assignment of new variables to be non-const");
1619         goto onerr;
1620         if (!parse_variable(parser, block))
1621             goto onerr;
1622     }
1623     else if (parser->tok != ';')
1624     {
1625         initexpr = parse_expression_leave(parser, false);
1626         if (!initexpr)
1627             goto onerr;
1628     }
1629
1630     /* move on to condition */
1631     if (parser->tok != ';') {
1632         parseerror(parser, "expected semicolon after for-loop initializer");
1633         goto onerr;
1634     }
1635     if (!parser_next(parser)) {
1636         parseerror(parser, "expected for-loop condition");
1637         goto onerr;
1638     }
1639
1640     /* parse the condition */
1641     if (parser->tok != ';') {
1642         cond = parse_expression_leave(parser, false);
1643         if (!cond)
1644             goto onerr;
1645     }
1646
1647     /* move on to incrementor */
1648     if (parser->tok != ';') {
1649         parseerror(parser, "expected semicolon after for-loop initializer");
1650         goto onerr;
1651     }
1652     if (!parser_next(parser)) {
1653         parseerror(parser, "expected for-loop condition");
1654         goto onerr;
1655     }
1656
1657     /* parse the incrementor */
1658     if (parser->tok != ')') {
1659         increment = parse_expression_leave(parser, false);
1660         if (!increment)
1661             goto onerr;
1662         if (!ast_istype(increment, ast_store) &&
1663             !ast_istype(increment, ast_call) &&
1664             !ast_istype(increment, ast_binstore))
1665         {
1666             if (genwarning(ast_ctx(increment), WARN_EFFECTLESS_STATEMENT, "statement has no effect"))
1667                 goto onerr;
1668         }
1669     }
1670
1671     /* closing paren */
1672     if (parser->tok != ')') {
1673         parseerror(parser, "expected closing paren after 'for-loop' incrementor");
1674         goto onerr;
1675     }
1676     /* parse into the 'then' branch */
1677     if (!parser_next(parser)) {
1678         parseerror(parser, "expected for-loop body");
1679         goto onerr;
1680     }
1681     ontrue = parse_statement_or_block(parser);
1682     if (!ontrue) {
1683         goto onerr;
1684     }
1685
1686     aloop = ast_loop_new(ctx, initexpr, cond, NULL, increment, ontrue);
1687     *out = (ast_expression*)aloop;
1688
1689     while (parser->locals_count > parser->blocklocal)
1690         retval = retval && parser_pop_local(parser);
1691     parser->blocklocal = oldblocklocal;
1692     return retval;
1693 onerr:
1694     if (initexpr)  ast_delete(initexpr);
1695     if (cond)      ast_delete(cond);
1696     if (increment) ast_delete(increment);
1697     while (parser->locals_count > parser->blocklocal)
1698         (void)!parser_pop_local(parser);
1699     parser->blocklocal = oldblocklocal;
1700     return false;
1701 }
1702
1703 static bool parse_statement(parser_t *parser, ast_block *block, ast_expression **out)
1704 {
1705     if (parser->tok == TOKEN_TYPENAME)
1706     {
1707         /* local variable */
1708         if (!block) {
1709             parseerror(parser, "cannot declare a variable from here");
1710             return false;
1711         }
1712         if (opts_standard == COMPILER_QCC) {
1713             if (parsewarning(parser, WARN_EXTENSIONS, "missing 'local' keyword when declaring a local variable"))
1714                 return false;
1715         }
1716         if (!parse_variable(parser, block))
1717             return false;
1718         *out = NULL;
1719         return true;
1720     }
1721     else if (parser->tok == TOKEN_KEYWORD)
1722     {
1723         if (!strcmp(parser_tokval(parser), "local"))
1724         {
1725             if (!block) {
1726                 parseerror(parser, "cannot declare a local variable here");
1727                 return false;
1728             }
1729             if (!parser_next(parser)) {
1730                 parseerror(parser, "expected variable declaration");
1731                 return false;
1732             }
1733             if (!parse_variable(parser, block))
1734                 return false;
1735             *out = NULL;
1736             return true;
1737         }
1738         else if (!strcmp(parser_tokval(parser), "return"))
1739         {
1740             ast_expression *exp = NULL;
1741             ast_return     *ret = NULL;
1742             ast_value      *expected = parser->function->vtype;
1743
1744             if (!parser_next(parser)) {
1745                 parseerror(parser, "expected return expression");
1746                 return false;
1747             }
1748
1749             if (parser->tok != ';') {
1750                 exp = parse_expression(parser, false);
1751                 if (!exp)
1752                     return false;
1753
1754                 if (exp->expression.vtype != expected->expression.next->expression.vtype) {
1755                     parseerror(parser, "return with invalid expression");
1756                 }
1757
1758                 ret = ast_return_new(exp->expression.node.context, exp);
1759                 if (!ret) {
1760                     ast_delete(exp);
1761                     return false;
1762                 }
1763             } else {
1764                 if (!parser_next(parser))
1765                     parseerror(parser, "parse error");
1766                 if (expected->expression.next->expression.vtype != TYPE_VOID) {
1767                     if (opts_standard != COMPILER_GMQCC)
1768                         (void)!parsewarning(parser, WARN_MISSING_RETURN_VALUES, "return without value");
1769                     else
1770                         parseerror(parser, "return without value");
1771                 }
1772                 ret = ast_return_new(parser_ctx(parser), NULL);
1773             }
1774             *out = (ast_expression*)ret;
1775             return true;
1776         }
1777         else if (!strcmp(parser_tokval(parser), "if"))
1778         {
1779             return parse_if(parser, block, out);
1780         }
1781         else if (!strcmp(parser_tokval(parser), "while"))
1782         {
1783             return parse_while(parser, block, out);
1784         }
1785         else if (!strcmp(parser_tokval(parser), "do"))
1786         {
1787             return parse_dowhile(parser, block, out);
1788         }
1789         else if (!strcmp(parser_tokval(parser), "for"))
1790         {
1791             if (opts_standard == COMPILER_QCC) {
1792                 if (parsewarning(parser, WARN_EXTENSIONS, "for loops are not recognized in the original Quake C standard, to enable try an alternate standard --std=?"))
1793                     return false;
1794             }
1795             return parse_for(parser, block, out);
1796         }
1797         parseerror(parser, "Unexpected keyword");
1798         return false;
1799     }
1800     else if (parser->tok == '{')
1801     {
1802         ast_block *inner;
1803         inner = parse_block(parser, false);
1804         if (!inner)
1805             return false;
1806         *out = (ast_expression*)inner;
1807         return true;
1808     }
1809     else
1810     {
1811         ast_expression *exp = parse_expression(parser, false);
1812         if (!exp)
1813             return false;
1814         *out = exp;
1815         if (!ast_istype(exp, ast_store) &&
1816             !ast_istype(exp, ast_call) &&
1817             !ast_istype(exp, ast_binstore))
1818         {
1819             if (genwarning(ast_ctx(exp), WARN_EFFECTLESS_STATEMENT, "statement has no effect"))
1820                 return false;
1821         }
1822         return true;
1823     }
1824 }
1825
1826 static bool GMQCC_WARN parser_pop_local(parser_t *parser)
1827 {
1828     varentry_t *ve;
1829     parser->locals_count--;
1830
1831     ve = &parser->locals[parser->locals_count];
1832     if (ast_istype(ve->var, ast_value) && !(((ast_value*)(ve->var))->uses)) {
1833         if (parsewarning(parser, WARN_UNUSED_VARIABLE, "unused variable: `%s`", ve->name))
1834             return false;
1835     }
1836     mem_d(parser->locals[parser->locals_count].name);
1837     return true;
1838 }
1839
1840 static bool parse_block_into(parser_t *parser, ast_block *block, bool warnreturn)
1841 {
1842     size_t oldblocklocal;
1843     bool   retval = true;
1844
1845     oldblocklocal = parser->blocklocal;
1846     parser->blocklocal = parser->locals_count;
1847
1848     if (!parser_next(parser)) { /* skip the '{' */
1849         parseerror(parser, "expected function body");
1850         goto cleanup;
1851     }
1852
1853     while (parser->tok != TOKEN_EOF && parser->tok < TOKEN_ERROR)
1854     {
1855         ast_expression *expr;
1856         if (parser->tok == '}')
1857             break;
1858
1859         if (!parse_statement(parser, block, &expr)) {
1860             /* parseerror(parser, "parse error"); */
1861             block = NULL;
1862             goto cleanup;
1863         }
1864         if (!expr)
1865             continue;
1866         if (!ast_block_exprs_add(block, expr)) {
1867             ast_delete(expr);
1868             block = NULL;
1869             goto cleanup;
1870         }
1871     }
1872
1873     if (parser->tok != '}') {
1874         block = NULL;
1875     } else {
1876         if (warnreturn && parser->function->vtype->expression.next->expression.vtype != TYPE_VOID)
1877         {
1878             if (!block->exprs_count ||
1879                 !ast_istype(block->exprs[block->exprs_count-1], ast_return))
1880             {
1881                 if (parsewarning(parser, WARN_MISSING_RETURN_VALUES, "control reaches end of non-void function")) {
1882                     block = NULL;
1883                     goto cleanup;
1884                 }
1885             }
1886         }
1887         (void)parser_next(parser);
1888     }
1889
1890 cleanup:
1891     while (parser->locals_count > parser->blocklocal)
1892         retval = retval && parser_pop_local(parser);
1893     parser->blocklocal = oldblocklocal;
1894     return !!block;
1895 }
1896
1897 static ast_block* parse_block(parser_t *parser, bool warnreturn)
1898 {
1899     ast_block *block;
1900     block = ast_block_new(parser_ctx(parser));
1901     if (!block)
1902         return NULL;
1903     if (!parse_block_into(parser, block, warnreturn)) {
1904         ast_block_delete(block);
1905         return NULL;
1906     }
1907     return block;
1908 }
1909
1910 static ast_expression* parse_statement_or_block(parser_t *parser)
1911 {
1912     ast_expression *expr = NULL;
1913     if (parser->tok == '{')
1914         return (ast_expression*)parse_block(parser, false);
1915     if (!parse_statement(parser, NULL, &expr))
1916         return NULL;
1917     return expr;
1918 }
1919
1920 /* loop method */
1921 static bool create_vector_members(parser_t *parser, ast_value *var, varentry_t *ve)
1922 {
1923     size_t i;
1924     size_t len = strlen(var->name);
1925
1926     for (i = 0; i < 3; ++i) {
1927         ve[i].var = (ast_expression*)ast_member_new(ast_ctx(var), (ast_expression*)var, i);
1928         if (!ve[i].var)
1929             break;
1930
1931         ve[i].name = (char*)mem_a(len+3);
1932         if (!ve[i].name) {
1933             ast_delete(ve[i].var);
1934             break;
1935         }
1936
1937         memcpy(ve[i].name, var->name, len);
1938         ve[i].name[len]   = '_';
1939         ve[i].name[len+1] = 'x'+i;
1940         ve[i].name[len+2] = 0;
1941     }
1942     if (i == 3)
1943         return true;
1944
1945     /* unroll */
1946     do {
1947         --i;
1948         mem_d(ve[i].name);
1949         ast_delete(ve[i].var);
1950         ve[i].name = NULL;
1951         ve[i].var  = NULL;
1952     } while (i);
1953     return false;
1954 }
1955
1956 static bool parse_function_body(parser_t *parser, ast_value *var)
1957 {
1958     ast_block      *block = NULL;
1959     ast_function   *func;
1960     ast_function   *old;
1961     size_t          parami;
1962
1963     ast_expression *framenum  = NULL;
1964     ast_expression *nextthink = NULL;
1965     /* None of the following have to be deleted */
1966     ast_expression *fld_think, *fld_nextthink, *fld_frame;
1967     ast_expression *gbl_time, *gbl_self;
1968     bool            has_frame_think;
1969
1970     bool retval = true;
1971
1972     has_frame_think = false;
1973     old = parser->function;
1974
1975     if (var->expression.variadic) {
1976         if (parsewarning(parser, WARN_VARIADIC_FUNCTION,
1977                          "variadic function with implementation will not be able to access additional parameters"))
1978         {
1979             return false;
1980         }
1981     }
1982
1983     if (parser->tok == '[') {
1984         /* got a frame definition: [ framenum, nextthink ]
1985          * this translates to:
1986          * self.frame = framenum;
1987          * self.nextthink = time + 0.1;
1988          * self.think = nextthink;
1989          */
1990         nextthink = NULL;
1991
1992         fld_think     = parser_find_field(parser, "think");
1993         fld_nextthink = parser_find_field(parser, "nextthink");
1994         fld_frame     = parser_find_field(parser, "frame");
1995         if (!fld_think || !fld_nextthink || !fld_frame) {
1996             parseerror(parser, "cannot use [frame,think] notation without the required fields");
1997             parseerror(parser, "please declare the following entityfields: `frame`, `think`, `nextthink`");
1998             return false;
1999         }
2000         gbl_time      = parser_find_global(parser, "time");
2001         gbl_self      = parser_find_global(parser, "self");
2002         if (!gbl_time || !gbl_self) {
2003             parseerror(parser, "cannot use [frame,think] notation without the required globals");
2004             parseerror(parser, "please declare the following globals: `time`, `self`");
2005             return false;
2006         }
2007
2008         if (!parser_next(parser))
2009             return false;
2010
2011         framenum = parse_expression_leave(parser, true);
2012         if (!framenum) {
2013             parseerror(parser, "expected a framenumber constant in[frame,think] notation");
2014             return false;
2015         }
2016         if (!ast_istype(framenum, ast_value) || !( (ast_value*)framenum )->isconst) {
2017             ast_unref(framenum);
2018             parseerror(parser, "framenumber in [frame,think] notation must be a constant");
2019             return false;
2020         }
2021
2022         if (parser->tok != ',') {
2023             ast_unref(framenum);
2024             parseerror(parser, "expected comma after frame number in [frame,think] notation");
2025             parseerror(parser, "Got a %i\n", parser->tok);
2026             return false;
2027         }
2028
2029         if (!parser_next(parser)) {
2030             ast_unref(framenum);
2031             return false;
2032         }
2033
2034         if (parser->tok == TOKEN_IDENT && !parser_find_var(parser, parser_tokval(parser)))
2035         {
2036             /* qc allows the use of not-yet-declared functions here
2037              * - this automatically creates a prototype */
2038             varentry_t      varent;
2039             ast_value      *thinkfunc;
2040             ast_expression *functype = fld_think->expression.next;
2041
2042             thinkfunc = ast_value_new(parser_ctx(parser), parser_tokval(parser), functype->expression.vtype);
2043             if (!thinkfunc || !ast_type_adopt(thinkfunc, functype)) {
2044                 ast_unref(framenum);
2045                 parseerror(parser, "failed to create implicit prototype for `%s`", parser_tokval(parser));
2046                 return false;
2047             }
2048
2049             if (!parser_next(parser)) {
2050                 ast_unref(framenum);
2051                 ast_delete(thinkfunc);
2052                 return false;
2053             }
2054
2055             varent.var = (ast_expression*)thinkfunc;
2056             varent.name = util_strdup(thinkfunc->name);
2057             if (!parser_t_globals_add(parser, varent)) {
2058                 ast_unref(framenum);
2059                 ast_delete(thinkfunc);
2060                 return false;
2061             }
2062             nextthink = (ast_expression*)thinkfunc;
2063
2064         } else {
2065             nextthink = parse_expression_leave(parser, true);
2066             if (!nextthink) {
2067                 ast_unref(framenum);
2068                 parseerror(parser, "expected a think-function in [frame,think] notation");
2069                 return false;
2070             }
2071         }
2072
2073         if (!ast_istype(nextthink, ast_value)) {
2074             parseerror(parser, "think-function in [frame,think] notation must be a constant");
2075             retval = false;
2076         }
2077
2078         if (retval && parser->tok != ']') {
2079             parseerror(parser, "expected closing `]` for [frame,think] notation");
2080             retval = false;
2081         }
2082
2083         if (retval && !parser_next(parser)) {
2084             retval = false;
2085         }
2086
2087         if (retval && parser->tok != '{') {
2088             parseerror(parser, "a function body has to be declared after a [frame,think] declaration");
2089             retval = false;
2090         }
2091
2092         if (!retval) {
2093             ast_unref(nextthink);
2094             ast_unref(framenum);
2095             return false;
2096         }
2097
2098         has_frame_think = true;
2099     }
2100
2101     block = ast_block_new(parser_ctx(parser));
2102     if (!block) {
2103         parseerror(parser, "failed to allocate block");
2104         if (has_frame_think) {
2105             ast_unref(nextthink);
2106             ast_unref(framenum);
2107         }
2108         return false;
2109     }
2110
2111     if (has_frame_think) {
2112         lex_ctx ctx;
2113         ast_expression *self_frame;
2114         ast_expression *self_nextthink;
2115         ast_expression *self_think;
2116         ast_expression *time_plus_1;
2117         ast_store *store_frame;
2118         ast_store *store_nextthink;
2119         ast_store *store_think;
2120
2121         ctx = parser_ctx(parser);
2122         self_frame     = (ast_expression*)ast_entfield_new(ctx, gbl_self, fld_frame);
2123         self_nextthink = (ast_expression*)ast_entfield_new(ctx, gbl_self, fld_nextthink);
2124         self_think     = (ast_expression*)ast_entfield_new(ctx, gbl_self, fld_think);
2125
2126         time_plus_1    = (ast_expression*)ast_binary_new(ctx, INSTR_ADD_F,
2127                          gbl_time, (ast_expression*)parser_const_float(parser, 0.1));
2128
2129         if (!self_frame || !self_nextthink || !self_think || !time_plus_1) {
2130             if (self_frame)     ast_delete(self_frame);
2131             if (self_nextthink) ast_delete(self_nextthink);
2132             if (self_think)     ast_delete(self_think);
2133             if (time_plus_1)    ast_delete(time_plus_1);
2134             retval = false;
2135         }
2136
2137         if (retval)
2138         {
2139             store_frame     = ast_store_new(ctx, INSTR_STOREP_F,   self_frame,     framenum);
2140             store_nextthink = ast_store_new(ctx, INSTR_STOREP_F,   self_nextthink, time_plus_1);
2141             store_think     = ast_store_new(ctx, INSTR_STOREP_FNC, self_think,     nextthink);
2142
2143             if (!store_frame) {
2144                 ast_delete(self_frame);
2145                 retval = false;
2146             }
2147             if (!store_nextthink) {
2148                 ast_delete(self_nextthink);
2149                 retval = false;
2150             }
2151             if (!store_think) {
2152                 ast_delete(self_think);
2153                 retval = false;
2154             }
2155             if (!retval) {
2156                 if (store_frame)     ast_delete(store_frame);
2157                 if (store_nextthink) ast_delete(store_nextthink);
2158                 if (store_think)     ast_delete(store_think);
2159                 retval = false;
2160             }
2161             if (retval && !ast_block_exprs_add(block, (ast_expression*)store_frame)) {
2162                 ast_delete(store_frame);
2163                 ast_delete(store_nextthink);
2164                 ast_delete(store_think);
2165                 retval = false;
2166             }
2167
2168             if (retval && !ast_block_exprs_add(block, (ast_expression*)store_nextthink)) {
2169                 ast_delete(store_nextthink);
2170                 ast_delete(store_think);
2171                 retval = false;
2172             }
2173
2174             if (retval && !ast_block_exprs_add(block, (ast_expression*)store_think) )
2175             {
2176                 ast_delete(store_think);
2177                 retval = false;
2178             }
2179         }
2180
2181         if (!retval) {
2182             parseerror(parser, "failed to generate code for [frame,think]");
2183             ast_unref(nextthink);
2184             ast_unref(framenum);
2185             ast_delete(block);
2186             return false;
2187         }
2188     }
2189
2190     for (parami = 0; parami < var->expression.params_count; ++parami) {
2191         size_t     e;
2192         varentry_t ve[3];
2193         ast_value *param = var->expression.params[parami];
2194
2195         if (param->expression.vtype != TYPE_VECTOR &&
2196             (param->expression.vtype != TYPE_FIELD ||
2197              param->expression.next->expression.vtype != TYPE_VECTOR))
2198         {
2199             continue;
2200         }
2201
2202         if (!create_vector_members(parser, param, ve)) {
2203             ast_block_delete(block);
2204             return false;
2205         }
2206
2207         for (e = 0; e < 3; ++e) {
2208             if (!parser_t_locals_add(parser, ve[e]))
2209                 break;
2210             if (!ast_block_collect(block, ve[e].var)) {
2211                 parser->locals_count--;
2212                 break;
2213             }
2214             ve[e].var = NULL; /* collected */
2215         }
2216         if (e != e) {
2217             parser->locals -= e;
2218             do {
2219                 mem_d(ve[e].name);
2220                 --e;
2221             } while (e);
2222             ast_block_delete(block);
2223             return false;
2224         }
2225     }
2226
2227     func = ast_function_new(ast_ctx(var), var->name, var);
2228     if (!func) {
2229         parseerror(parser, "failed to allocate function for `%s`", var->name);
2230         ast_block_delete(block);
2231         goto enderr;
2232     }
2233     if (!parser_t_functions_add(parser, func)) {
2234         parseerror(parser, "failed to allocate slot for function `%s`", var->name);
2235         ast_block_delete(block);
2236         goto enderrfn;
2237     }
2238
2239     parser->function = func;
2240     if (!parse_block_into(parser, block, true)) {
2241         ast_block_delete(block);
2242         goto enderrfn2;
2243     }
2244
2245     if (!ast_function_blocks_add(func, block)) {
2246         ast_block_delete(block);
2247         goto enderrfn2;
2248     }
2249
2250     parser->function = old;
2251     while (parser->locals_count)
2252         retval = retval && parser_pop_local(parser);
2253
2254     if (parser->tok == ';')
2255         return parser_next(parser);
2256     else if (opts_standard == COMPILER_QCC)
2257         parseerror(parser, "missing semicolon after function body (mandatory with -std=qcc)");
2258     return retval;
2259
2260 enderrfn2:
2261     parser->functions_count--;
2262 enderrfn:
2263     ast_function_delete(func);
2264     var->constval.vfunc = NULL;
2265
2266 enderr:
2267     while (parser->locals_count) {
2268         parser->locals_count--;
2269         mem_d(parser->locals[parser->locals_count].name);
2270     }
2271     parser->function = old;
2272     return false;
2273 }
2274
2275 static bool parse_variable(parser_t *parser, ast_block *localblock)
2276 {
2277     bool            isfunc = false;
2278     lex_ctx         ctx;
2279
2280     ast_value      *var = NULL;
2281     bool cleanvar = false;
2282
2283     varentry_t      varent;
2284     varentry_t      ve[3];
2285
2286     ast_expression *olddecl;
2287
2288     ast_value      *typevar;
2289
2290     bool hadproto;
2291     bool isparam;
2292
2293     bool retval = true;
2294
2295     /* go */
2296
2297     int basetype = parser_token(parser)->constval.t;
2298
2299     if (!parser_next(parser)) {
2300         parseerror(parser, "expected variable definition");
2301         return false;
2302     }
2303
2304     typevar = parse_type(parser, basetype, &isfunc);
2305     if (!typevar)
2306         return false;
2307
2308     while (true)
2309     {
2310         hadproto    = false;
2311         olddecl     = NULL;
2312         isparam     = false;
2313         varent.name = NULL;
2314
2315         ve[0].name = ve[1].name = ve[2].name = NULL;
2316         ve[0].var  = ve[1].var  = ve[2].var  = NULL;
2317
2318         ctx = parser_ctx(parser);
2319         var = ast_value_copy(typevar);
2320         cleanvar = true;
2321
2322         if (!var) {
2323             parseerror(parser, "failed to create variable");
2324             retval = false;
2325             goto cleanup;
2326         }
2327
2328         if (parser->tok != TOKEN_IDENT) {
2329             parseerror(parser, "expected variable name");
2330             retval = false;
2331             goto cleanup;
2332         }
2333
2334         if (!localblock) {
2335             if      (!strcmp(parser_tokval(parser), "end_sys_globals"))
2336                 parser->crc_globals = parser->globals_count;
2337             else if (!strcmp(parser_tokval(parser), "end_sys_fields"))
2338                 parser->crc_fields = parser->fields_count;
2339         }
2340
2341         if (!isfunc) {
2342             if (!localblock && (olddecl = parser_find_global(parser, parser_tokval(parser)))) {
2343                 parseerror(parser, "global `%s` already declared here: %s:%i",
2344                            parser_tokval(parser), ast_ctx(olddecl).file, (int)ast_ctx(olddecl).line);
2345                 retval = false;
2346                 goto cleanup;
2347             }
2348
2349             if (localblock) {
2350                 olddecl = parser_find_local(parser, parser_tokval(parser), parser->blocklocal, &isparam);
2351                 if (opts_standard == COMPILER_GMQCC)
2352                 {
2353                     if (olddecl)
2354                     {
2355                         if (!isparam) {
2356                             parseerror(parser, "local `%s` already declared here: %s:%i",
2357                                        parser_tokval(parser), ast_ctx(olddecl).file, (int)ast_ctx(olddecl).line);
2358                             retval = false;
2359                             goto cleanup;
2360                         }
2361                     }
2362
2363                     if( (!isparam && olddecl) ||
2364                         (olddecl = parser_find_local(parser, parser_tokval(parser), 0, &isparam))
2365                       )
2366                     {
2367                         if (parsewarning(parser, WARN_LOCAL_SHADOWS,
2368                                          "local `%s` is shadowing a parameter", parser_tokval(parser)))
2369                         {
2370                             parseerror(parser, "local `%s` already declared here: %s:%i",
2371                                        parser_tokval(parser), ast_ctx(olddecl).file, (int)ast_ctx(olddecl).line);
2372                             retval = false;
2373                             goto cleanup;
2374                         }
2375                     }
2376                 }
2377                 else
2378                 {
2379                     if (olddecl)
2380                     {
2381                         ast_value_delete(var);
2382                         var = NULL;
2383                         if (isparam &&
2384                             parsewarning(parser, WARN_LOCAL_SHADOWS,
2385                                          "a parameter is shadowing local `%s`", parser_tokval(parser)))
2386                         {
2387                             retval = false;
2388                             goto cleanup;
2389                         }
2390                         else if (!isparam)
2391                         {
2392                             parseerror(parser, "local `%s` already declared here: %s:%i",
2393                                        parser_tokval(parser), ast_ctx(olddecl).file, (int)ast_ctx(olddecl).line);
2394                             retval = false;
2395                             goto cleanup;
2396                         }
2397                         goto nextvar;
2398                     }
2399                 }
2400             }
2401         }
2402
2403         if (!ast_value_set_name(var, parser_tokval(parser))) {
2404             parseerror(parser, "failed to set variable name\n");
2405             retval = false;
2406             goto cleanup;
2407         }
2408
2409         if (isfunc) {
2410             /* a function was defined */
2411             ast_value *fval;
2412             ast_value *proto = NULL;
2413             bool dummy;
2414
2415             if (!localblock)
2416                 olddecl = parser_find_global(parser, parser_tokval(parser));
2417             else
2418                 olddecl = parser_find_local(parser, parser_tokval(parser), parser->blocklocal, &dummy);
2419
2420             if (olddecl) {
2421                 /* we had a prototype */
2422                 if (!ast_istype(olddecl, ast_value)) {
2423                     /* vector v;
2424                      * void() v_x = {}
2425                      */
2426                     parseerror(parser, "cannot declare a function with the same name as a vector's member: %s",
2427                                parser_tokval(parser));
2428                     retval = false;
2429                     goto cleanup;
2430                 }
2431
2432                 proto = (ast_value*)olddecl;
2433             }
2434
2435             /* turn var into a value of TYPE_FUNCTION, with the old var
2436              * as return type
2437              */
2438             fval = ast_value_new(ctx, var->name, TYPE_FUNCTION);
2439             if (!fval) {
2440                 retval = false;
2441                 goto cleanup;
2442             }
2443
2444             fval->expression.next = (ast_expression*)var;
2445             MEM_VECTOR_MOVE(&var->expression, params, &fval->expression, params);
2446             fval->expression.variadic = var->expression.variadic;
2447             var = NULL;
2448
2449             /* we compare the type late here, but it's easier than
2450              * messing with the parameter-vector etc. earlier
2451              */
2452             if (proto) {
2453                 size_t param;
2454                 if (!ast_compare_type((ast_expression*)proto, (ast_expression*)fval)) {
2455                     parseerror(parser, "conflicting types for `%s`, previous declaration was here: %s:%i",
2456                                proto->name,
2457                                ast_ctx(proto).file, ast_ctx(proto).line);
2458                     ast_value_delete(fval);
2459                     retval = false;
2460                     goto cleanup;
2461                 }
2462                 /* copy over the parameter names */
2463                 for (param = 0; param < fval->expression.params_count; ++param)
2464                     ast_value_set_name(proto->expression.params[param], fval->expression.params[param]->name);
2465                 /* copy the new context */
2466                 ast_ctx(proto) = ast_ctx(fval);
2467
2468                 /* now ditch the rest of the new data */
2469                 ast_value_delete(fval);
2470                 fval = proto;
2471                 hadproto = true;
2472             }
2473
2474             var = fval;
2475         }
2476
2477         if (!hadproto) {
2478             varent.name = util_strdup(var->name);
2479             varent.var = (ast_expression*)var;
2480
2481             if (!localblock) {
2482                 if (!(retval = parser_t_globals_add(parser, varent)))
2483                     goto cleanup;
2484             } else {
2485                 if (!(retval = parser_t_locals_add(parser, varent)))
2486                     goto cleanup;
2487                 if (!(retval = ast_block_locals_add(localblock, var))) {
2488                     parser->locals_count--;
2489                     goto cleanup;
2490                 }
2491             }
2492
2493             if (var->expression.vtype == TYPE_VECTOR)
2494             {
2495                 size_t e;
2496                 if (!create_vector_members(parser, var, ve)) {
2497                     retval = false;
2498                     goto cleanup;
2499                 }
2500
2501                 if (!localblock) {
2502                     for (e = 0; e < 3; ++e) {
2503                         if (!(retval = parser_t_globals_add(parser, ve[e])))
2504                             break;
2505                     }
2506                     if (!retval) {
2507                         parser->globals_count -= e+1;
2508                         goto cleanup;
2509                     }
2510                 } else {
2511                     for (e = 0; e < 3; ++e) {
2512                         if (!(retval = parser_t_locals_add(parser, ve[e])))
2513                             break;
2514                         if (!(retval = ast_block_collect(localblock, ve[e].var)))
2515                             break;
2516                         ve[e].var = NULL; /* from here it's being collected in the block */
2517                     }
2518                     if (!retval) {
2519                         parser->locals_count -= e+1;
2520                         localblock->locals_count--;
2521                         goto cleanup;
2522                     }
2523                 }
2524                 ve[0].name = ve[1].name = ve[2].name = NULL;
2525                 ve[0].var  = ve[1].var  = ve[2].var  = NULL;
2526             }
2527             cleanvar = false;
2528             varent.name = NULL;
2529         }
2530
2531 nextvar:
2532         if (!(retval = parser_next(parser)))
2533             goto cleanup;
2534
2535         if (parser->tok == ';') {
2536             ast_value_delete(typevar);
2537             return parser_next(parser);
2538         }
2539
2540         if (parser->tok == ',') {
2541             /* another var */
2542             if (!(retval = parser_next(parser)))
2543                 goto cleanup;
2544             continue;
2545         }
2546
2547         /* NOTE: only 'typevar' needs to be deleted from here on, so 'cleanup' won't be used
2548          * to avoid having too many gotos
2549          */
2550         if (localblock && opts_standard == COMPILER_QCC) {
2551             if (parsewarning(parser, WARN_LOCAL_CONSTANTS,
2552                              "initializing expression turns variable `%s` into a constant in this standard",
2553                              var->name) )
2554             {
2555                 ast_value_delete(typevar);
2556                 return false;
2557             }
2558         }
2559
2560         if (parser->tok != '=') {
2561             if (opts_standard == COMPILER_QCC)
2562                 parseerror(parser, "missing semicolon");
2563             else
2564                 parseerror(parser, "missing semicolon or initializer");
2565             ast_value_delete(typevar);
2566             return false;
2567         }
2568
2569         if (!parser_next(parser)) {
2570             ast_value_delete(typevar);
2571             return false;
2572         }
2573
2574         if (parser->tok == '#') {
2575             ast_function *func;
2576
2577             if (localblock) {
2578                 parseerror(parser, "cannot declare builtins within functions");
2579                 ast_value_delete(typevar);
2580                 return false;
2581             }
2582             if (!isfunc) {
2583                 parseerror(parser, "unexpected builtin number, '%s' is not a function", var->name);
2584                 ast_value_delete(typevar);
2585                 return false;
2586             }
2587             if (!parser_next(parser)) {
2588                 parseerror(parser, "expected builtin number");
2589                 ast_value_delete(typevar);
2590                 return false;
2591             }
2592             if (parser->tok != TOKEN_INTCONST) {
2593                 parseerror(parser, "builtin number must be an integer constant");
2594                 ast_value_delete(typevar);
2595                 return false;
2596             }
2597             if (parser_token(parser)->constval.i <= 0) {
2598                 parseerror(parser, "builtin number must be positive integer greater than zero");
2599                 ast_value_delete(typevar);
2600                 return false;
2601             }
2602
2603             func = ast_function_new(ast_ctx(var), var->name, var);
2604             if (!func) {
2605                 parseerror(parser, "failed to allocate function for `%s`", var->name);
2606                 ast_value_delete(typevar);
2607                 return false;
2608             }
2609             if (!parser_t_functions_add(parser, func)) {
2610                 parseerror(parser, "failed to allocate slot for function `%s`", var->name);
2611                 ast_function_delete(func);
2612                 var->constval.vfunc = NULL;
2613                 ast_value_delete(typevar);
2614                 return false;
2615             }
2616
2617             func->builtin = -parser_token(parser)->constval.i;
2618
2619             if (!parser_next(parser)) {
2620                 ast_value_delete(typevar);
2621                 return false;
2622             }
2623         }
2624         else if (parser->tok == '{' || parser->tok == '[')
2625         {
2626             ast_value_delete(typevar);
2627             if (localblock) {
2628                 parseerror(parser, "cannot declare functions within functions");
2629                 return false;
2630             }
2631
2632             if (!parse_function_body(parser, var)) {
2633                 return false;
2634             }
2635             return true;
2636         } else {
2637             ast_expression *cexp;
2638             ast_value      *cval;
2639
2640             cexp = parse_expression_leave(parser, true);
2641             if (!cexp) {
2642                 ast_value_delete(typevar);
2643                 return false;
2644             }
2645
2646             cval = (ast_value*)cexp;
2647             if (!ast_istype(cval, ast_value) || !cval->isconst)
2648                 parseerror(parser, "cannot initialize a global constant variable with a non-constant expression");
2649             else
2650             {
2651                 var->isconst = true;
2652                 if (cval->expression.vtype == TYPE_STRING)
2653                     var->constval.vstring = parser_strdup(cval->constval.vstring);
2654                 else
2655                     memcpy(&var->constval, &cval->constval, sizeof(var->constval));
2656                 ast_unref(cval);
2657             }
2658         }
2659
2660         if (parser->tok == ',') {
2661             /* another */
2662             continue;
2663         }
2664
2665         if (parser->tok != ';') {
2666             parseerror(parser, "missing semicolon");
2667             ast_value_delete(typevar);
2668             return false;
2669         }
2670
2671         (void)parser_next(parser);
2672
2673         ast_value_delete(typevar);
2674         return true;
2675     }
2676
2677 cleanup:
2678     ast_delete(typevar);
2679     if (var && cleanvar) ast_delete(var);
2680     if (varent.name) mem_d(varent.name);
2681     if (ve[0].name)  mem_d(ve[0].name);
2682     if (ve[1].name)  mem_d(ve[1].name);
2683     if (ve[2].name)  mem_d(ve[2].name);
2684     if (ve[0].var)   mem_d(ve[0].var);
2685     if (ve[1].var)   mem_d(ve[1].var);
2686     if (ve[2].var)   mem_d(ve[2].var);
2687
2688     return retval;
2689 }
2690
2691 static bool parser_global_statement(parser_t *parser)
2692 {
2693     if (parser->tok == TOKEN_TYPENAME)
2694     {
2695         return parse_variable(parser, NULL);
2696     }
2697     else if (parser->tok == TOKEN_KEYWORD)
2698     {
2699         /* handle 'var' and 'const' */
2700         return false;
2701     }
2702     else if (parser->tok == '.')
2703     {
2704         ast_value *var;
2705         ast_value *typevar;
2706         ast_value *fld;
2707         ast_expression *oldex;
2708         bool       isfunc = false;
2709         int        basetype;
2710         lex_ctx    ctx = parser_ctx(parser);
2711         varentry_t varent;
2712
2713         /* entity-member declaration */
2714         if (!parser_next(parser) || parser->tok != TOKEN_TYPENAME) {
2715             parseerror(parser, "expected member variable definition");
2716             return false;
2717         }
2718
2719         /* remember the base/return type */
2720         basetype = parser_token(parser)->constval.t;
2721
2722         /* parse into the declaration */
2723         if (!parser_next(parser)) {
2724             parseerror(parser, "expected field definition");
2725             return false;
2726         }
2727
2728         /* parse the field type fully */
2729         typevar = var = parse_type(parser, basetype, &isfunc);
2730         if (!var)
2731             return false;
2732
2733         while (true) {
2734             var = ast_value_copy(typevar);
2735             /* now the field name */
2736             if (parser->tok != TOKEN_IDENT) {
2737                 parseerror(parser, "expected field name");
2738                 ast_delete(var);
2739                 return false;
2740             }
2741
2742             /* check for an existing field
2743              * in original qc we also have to check for an existing
2744              * global named like the field
2745              */
2746             if (opts_standard == COMPILER_QCC) {
2747                 if (parser_find_global(parser, parser_tokval(parser))) {
2748                     parseerror(parser, "cannot declare a field and a global of the same name with -std=qcc");
2749                     ast_delete(var);
2750                     return false;
2751                 }
2752             }
2753
2754             if (isfunc) {
2755                 ast_value *fval;
2756                 fval = ast_value_new(ctx, var->name, TYPE_FUNCTION);
2757                 if (!fval) {
2758                     ast_value_delete(var);
2759                     return false;
2760                 }
2761                 fval->expression.next = (ast_expression*)var;
2762                 MEM_VECTOR_MOVE(&var->expression, params, &fval->expression, params);
2763                 fval->expression.variadic = var->expression.variadic;
2764                 var = fval;
2765             }
2766
2767             if (!strcmp(parser_tokval(parser), "end_sys_fields")) {
2768                 if (parsewarning(parser, WARN_END_SYS_FIELDS, "by convention end_sys_fields should be declared as global, rather than a field")) {
2769                     ast_value_delete(var);
2770                     return false;
2771                 }
2772             }
2773
2774             /* turn it into a field */
2775             fld = ast_value_new(ctx, parser_tokval(parser), TYPE_FIELD);
2776             fld->expression.next = (ast_expression*)var;
2777
2778             if ( (oldex = parser_find_field(parser, parser_tokval(parser)))) {
2779                 if (ast_istype(oldex, ast_member)) {
2780                     parseerror(parser, "cannot declare a field with the same name as a vector component, component %s has been declared here: %s:%i",
2781                                parser_tokval(parser), ast_ctx(oldex).file, (int)ast_ctx(oldex).line);
2782                     ast_delete(fld);
2783                     return false;
2784                 }
2785                 if (!ast_istype(oldex, ast_value)) {
2786                     /* not possible / sanity check */
2787                     parseerror(parser, "internal error: %s is not an ast_value", parser_tokval(parser));
2788                     ast_delete(fld);
2789                     return false;
2790                 }
2791
2792                 if (!ast_compare_type(oldex, (ast_expression*)fld)) {
2793                     parseerror(parser, "field %s has previously been declared with a different type here: %s:%i",
2794                                parser_tokval(parser), ast_ctx(oldex).file, (int)ast_ctx(oldex).line);
2795                     ast_delete(fld);
2796                     return false;
2797                 } else {
2798                     if (parsewarning(parser, WARN_FIELD_REDECLARED, "field `%s` has already been declared here: %s:%i",
2799                                      parser_tokval(parser), ast_ctx(oldex).file, (int)ast_ctx(oldex).line))
2800                     {
2801                         ast_delete(fld);
2802                         return false;
2803                     }
2804                 }
2805
2806                 ast_delete(fld);
2807                 goto nextfield;
2808             }
2809
2810             varent.var = (ast_expression*)fld;
2811             varent.name = util_strdup(fld->name);
2812             (void)!parser_t_fields_add(parser, varent);
2813
2814             if (var->expression.vtype == TYPE_VECTOR)
2815             {
2816                 /* create _x, _y and _z fields as well */
2817                 varentry_t ve[3];
2818                 if (!create_vector_members(parser, fld, ve)) {
2819                     ast_delete(fld);
2820                     return false;
2821                 }
2822                 (void)!parser_t_fields_add(parser, ve[0]);
2823                 (void)!parser_t_fields_add(parser, ve[1]);
2824                 (void)!parser_t_fields_add(parser, ve[2]);
2825             }
2826
2827 nextfield:
2828             if (!parser_next(parser)) {
2829                 parseerror(parser, "expected semicolon or another field name");
2830                 return false;
2831             }
2832             if (parser->tok == ';')
2833                 break;
2834             if (parser->tok != ',' || !parser_next(parser)) {
2835                 parseerror(parser, "expected semicolon or another field name");
2836                 return false;
2837             }
2838         }
2839         ast_delete(typevar);
2840
2841         /* skip the semicolon */
2842         if (!parser_next(parser))
2843             return parser->tok == TOKEN_EOF;
2844
2845         return true;
2846     }
2847     else if (parser->tok == '$')
2848     {
2849         if (!parser_next(parser)) {
2850             parseerror(parser, "parse error");
2851             return false;
2852         }
2853     }
2854     else
2855     {
2856         parseerror(parser, "unexpected token: %s", parser->lex->tok.value);
2857         return false;
2858     }
2859     return true;
2860 }
2861
2862 static parser_t *parser;
2863
2864 bool parser_init()
2865 {
2866     parser = (parser_t*)mem_a(sizeof(parser_t));
2867     if (!parser)
2868         return false;
2869
2870     memset(parser, 0, sizeof(*parser));
2871     return true;
2872 }
2873
2874 bool parser_compile(const char *filename)
2875 {
2876     parser->lex = lex_open(filename);
2877     if (!parser->lex) {
2878         printf("failed to open file \"%s\"\n", filename);
2879         return false;
2880     }
2881
2882     /* initial lexer/parser state */
2883     parser->lex->flags.noops = true;
2884
2885     if (parser_next(parser))
2886     {
2887         while (parser->tok != TOKEN_EOF && parser->tok < TOKEN_ERROR)
2888         {
2889             if (!parser_global_statement(parser)) {
2890                 if (parser->tok == TOKEN_EOF)
2891                     parseerror(parser, "unexpected eof");
2892                 else if (!parser->errors)
2893                     parseerror(parser, "there have been errors, bailing out");
2894                 lex_close(parser->lex);
2895                 parser->lex = NULL;
2896                 return false;
2897             }
2898         }
2899     } else {
2900         parseerror(parser, "parse error");
2901         lex_close(parser->lex);
2902         parser->lex = NULL;
2903         return false;
2904     }
2905
2906     lex_close(parser->lex);
2907     parser->lex = NULL;
2908
2909     return !parser->errors;
2910 }
2911
2912 void parser_cleanup()
2913 {
2914     size_t i;
2915     for (i = 0; i < parser->functions_count; ++i) {
2916         ast_delete(parser->functions[i]);
2917     }
2918     for (i = 0; i < parser->imm_vector_count; ++i) {
2919         ast_delete(parser->imm_vector[i]);
2920     }
2921     for (i = 0; i < parser->imm_string_count; ++i) {
2922         ast_delete(parser->imm_string[i]);
2923     }
2924     for (i = 0; i < parser->imm_float_count; ++i) {
2925         ast_delete(parser->imm_float[i]);
2926     }
2927     for (i = 0; i < parser->fields_count; ++i) {
2928         ast_delete(parser->fields[i].var);
2929         mem_d(parser->fields[i].name);
2930     }
2931     for (i = 0; i < parser->globals_count; ++i) {
2932         ast_delete(parser->globals[i].var);
2933         mem_d(parser->globals[i].name);
2934     }
2935     MEM_VECTOR_CLEAR(parser, functions);
2936     MEM_VECTOR_CLEAR(parser, imm_vector);
2937     MEM_VECTOR_CLEAR(parser, imm_string);
2938     MEM_VECTOR_CLEAR(parser, imm_float);
2939     MEM_VECTOR_CLEAR(parser, globals);
2940     MEM_VECTOR_CLEAR(parser, fields);
2941     MEM_VECTOR_CLEAR(parser, locals);
2942
2943     mem_d(parser);
2944 }
2945
2946 static uint16_t progdefs_crc_sum(uint16_t old, const char *str)
2947 {
2948     return util_crc16(old, str, strlen(str));
2949 }
2950
2951 static void progdefs_crc_file(const char *str)
2952 {
2953     /* write to progdefs.h here */
2954 }
2955
2956 static uint16_t progdefs_crc_both(uint16_t old, const char *str)
2957 {
2958     old = progdefs_crc_sum(old, str);
2959     progdefs_crc_file(str);
2960     return old;
2961 }
2962
2963 static void generate_checksum(parser_t *parser)
2964 {
2965     uint16_t crc = 0xFFFF;
2966     size_t i;
2967
2968         crc = progdefs_crc_both(crc, "\n/* file generated by qcc, do not modify */\n\ntypedef struct\n{");
2969         crc = progdefs_crc_sum(crc, "\tint\tpad[28];\n");
2970         /*
2971         progdefs_crc_file("\tint\tpad;\n");
2972         progdefs_crc_file("\tint\tofs_return[3];\n");
2973         progdefs_crc_file("\tint\tofs_parm0[3];\n");
2974         progdefs_crc_file("\tint\tofs_parm1[3];\n");
2975         progdefs_crc_file("\tint\tofs_parm2[3];\n");
2976         progdefs_crc_file("\tint\tofs_parm3[3];\n");
2977         progdefs_crc_file("\tint\tofs_parm4[3];\n");
2978         progdefs_crc_file("\tint\tofs_parm5[3];\n");
2979         progdefs_crc_file("\tint\tofs_parm6[3];\n");
2980         progdefs_crc_file("\tint\tofs_parm7[3];\n");
2981         */
2982         for (i = 0; i < parser->crc_globals; ++i) {
2983             if (!ast_istype(parser->globals[i].var, ast_value))
2984                 continue;
2985             switch (parser->globals[i].var->expression.vtype) {
2986                 case TYPE_FLOAT:    crc = progdefs_crc_both(crc, "\tfloat\t"); break;
2987                 case TYPE_VECTOR:   crc = progdefs_crc_both(crc, "\tvec3_t\t"); break;
2988                 case TYPE_STRING:   crc = progdefs_crc_both(crc, "\tstring_t\t"); break;
2989                 case TYPE_FUNCTION: crc = progdefs_crc_both(crc, "\tfunc_t\t"); break;
2990                 default:
2991                     crc = progdefs_crc_both(crc, "\tint\t");
2992                     break;
2993             }
2994             crc = progdefs_crc_both(crc, parser->globals[i].name);
2995             crc = progdefs_crc_both(crc, ";\n");
2996         }
2997         crc = progdefs_crc_both(crc, "} globalvars_t;\n\ntypedef struct\n{\n");
2998         for (i = 0; i < parser->crc_fields; ++i) {
2999             if (!ast_istype(parser->fields[i].var, ast_value))
3000                 continue;
3001             switch (parser->fields[i].var->expression.next->expression.vtype) {
3002                 case TYPE_FLOAT:    crc = progdefs_crc_both(crc, "\tfloat\t"); break;
3003                 case TYPE_VECTOR:   crc = progdefs_crc_both(crc, "\tvec3_t\t"); break;
3004                 case TYPE_STRING:   crc = progdefs_crc_both(crc, "\tstring_t\t"); break;
3005                 case TYPE_FUNCTION: crc = progdefs_crc_both(crc, "\tfunc_t\t"); break;
3006                 default:
3007                     crc = progdefs_crc_both(crc, "\tint\t");
3008                     break;
3009             }
3010             crc = progdefs_crc_both(crc, parser->fields[i].name);
3011             crc = progdefs_crc_both(crc, ";\n");
3012         }
3013         crc = progdefs_crc_both(crc, "} entvars_t;\n\n");
3014
3015         code_crc = crc;
3016 }
3017
3018 bool parser_finish(const char *output)
3019 {
3020     size_t i;
3021     ir_builder *ir;
3022     bool retval = true;
3023
3024     if (!parser->errors)
3025     {
3026         ir = ir_builder_new("gmqcc_out");
3027         if (!ir) {
3028             printf("failed to allocate builder\n");
3029             return false;
3030         }
3031
3032         for (i = 0; i < parser->fields_count; ++i) {
3033             ast_value *field;
3034             bool isconst;
3035             if (!ast_istype(parser->fields[i].var, ast_value))
3036                 continue;
3037             field = (ast_value*)parser->fields[i].var;
3038             isconst = field->isconst;
3039             field->isconst = false;
3040             if (!ast_global_codegen((ast_value*)field, ir)) {
3041                 printf("failed to generate field %s\n", field->name);
3042                 ir_builder_delete(ir);
3043                 return false;
3044             }
3045             if (isconst) {
3046                 ir_value *ifld;
3047                 ast_expression *subtype;
3048                 field->isconst = true;
3049                 subtype = field->expression.next;
3050                 ifld = ir_builder_create_field(ir, field->name, subtype->expression.vtype);
3051                 if (subtype->expression.vtype == TYPE_FIELD)
3052                     ifld->fieldtype = subtype->expression.next->expression.vtype;
3053                 else if (subtype->expression.vtype == TYPE_FUNCTION)
3054                     ifld->outtype = subtype->expression.next->expression.vtype;
3055                 (void)!ir_value_set_field(field->ir_v, ifld);
3056             }
3057         }
3058         for (i = 0; i < parser->globals_count; ++i) {
3059             ast_value *asvalue;
3060             if (!ast_istype(parser->globals[i].var, ast_value))
3061                 continue;
3062             asvalue = (ast_value*)(parser->globals[i].var);
3063             if (!asvalue->uses && !asvalue->isconst && asvalue->expression.vtype != TYPE_FUNCTION) {
3064                 if (strcmp(asvalue->name, "end_sys_globals") &&
3065                     strcmp(asvalue->name, "end_sys_fields"))
3066                 {
3067                     retval = retval && !genwarning(ast_ctx(asvalue), WARN_UNUSED_VARIABLE,
3068                                                    "unused global: `%s`", asvalue->name);
3069                 }
3070             }
3071             if (!ast_global_codegen(asvalue, ir)) {
3072                 printf("failed to generate global %s\n", parser->globals[i].name);
3073                 ir_builder_delete(ir);
3074                 return false;
3075             }
3076         }
3077         for (i = 0; i < parser->imm_float_count; ++i) {
3078             if (!ast_global_codegen(parser->imm_float[i], ir)) {
3079                 printf("failed to generate global %s\n", parser->imm_float[i]->name);
3080                 ir_builder_delete(ir);
3081                 return false;
3082             }
3083         }
3084         for (i = 0; i < parser->imm_string_count; ++i) {
3085             if (!ast_global_codegen(parser->imm_string[i], ir)) {
3086                 printf("failed to generate global %s\n", parser->imm_string[i]->name);
3087                 ir_builder_delete(ir);
3088                 return false;
3089             }
3090         }
3091         for (i = 0; i < parser->imm_vector_count; ++i) {
3092             if (!ast_global_codegen(parser->imm_vector[i], ir)) {
3093                 printf("failed to generate global %s\n", parser->imm_vector[i]->name);
3094                 ir_builder_delete(ir);
3095                 return false;
3096             }
3097         }
3098         for (i = 0; i < parser->functions_count; ++i) {
3099             if (!ast_function_codegen(parser->functions[i], ir)) {
3100                 printf("failed to generate function %s\n", parser->functions[i]->name);
3101                 ir_builder_delete(ir);
3102                 return false;
3103             }
3104             if (!ir_function_finalize(parser->functions[i]->ir_func)) {
3105                 printf("failed to finalize function %s\n", parser->functions[i]->name);
3106                 ir_builder_delete(ir);
3107                 return false;
3108             }
3109         }
3110
3111         if (retval) {
3112             if (opts_dump)
3113                 ir_builder_dump(ir, printf);
3114
3115             generate_checksum(parser);
3116
3117             if (!ir_builder_generate(ir, output)) {
3118                 printf("*** failed to generate output file\n");
3119                 ir_builder_delete(ir);
3120                 return false;
3121             }
3122         }
3123
3124         ir_builder_delete(ir);
3125         return retval;
3126     }
3127
3128     printf("*** there were compile errors\n");
3129     return false;
3130 }