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