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