]> git.xonotic.org Git - xonotic/gmqcc.git/blob - parser.c
parser_compile_file vs parser_compile_string
[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(printf("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                 printf("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(printf("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(printf("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(printf("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(printf("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(printf("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(printf("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(printf("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(printf("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(printf("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(printf("push [nop] (\n"));
1365                 }
1366                 wantop = false;
1367             } else {
1368                 DEBUGSHUNTDO(printf("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(printf("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
1422     lex_ctx ctx = parser_ctx(parser);
1423
1424     /* skip the 'if' and check for opening paren */
1425     if (!parser_next(parser) || parser->tok != '(') {
1426         parseerror(parser, "expected 'if' condition in parenthesis");
1427         return false;
1428     }
1429     /* parse into the expression */
1430     if (!parser_next(parser)) {
1431         parseerror(parser, "expected 'if' condition after opening paren");
1432         return false;
1433     }
1434     /* parse the condition */
1435     cond = parse_expression_leave(parser, false);
1436     if (!cond)
1437         return false;
1438     /* closing paren */
1439     if (parser->tok != ')') {
1440         parseerror(parser, "expected closing paren after 'if' condition");
1441         ast_delete(cond);
1442         return false;
1443     }
1444     /* parse into the 'then' branch */
1445     if (!parser_next(parser)) {
1446         parseerror(parser, "expected statement for on-true branch of 'if'");
1447         ast_delete(cond);
1448         return false;
1449     }
1450     ontrue = parse_statement_or_block(parser);
1451     if (!ontrue) {
1452         ast_delete(cond);
1453         return false;
1454     }
1455     /* check for an else */
1456     if (!strcmp(parser_tokval(parser), "else")) {
1457         /* parse into the 'else' branch */
1458         if (!parser_next(parser)) {
1459             parseerror(parser, "expected on-false branch after 'else'");
1460             ast_delete(ontrue);
1461             ast_delete(cond);
1462             return false;
1463         }
1464         onfalse = parse_statement_or_block(parser);
1465         if (!onfalse) {
1466             ast_delete(ontrue);
1467             ast_delete(cond);
1468             return false;
1469         }
1470     }
1471
1472     ifthen = ast_ifthen_new(ctx, cond, ontrue, onfalse);
1473     *out = (ast_expression*)ifthen;
1474     return true;
1475 }
1476
1477 static bool parse_while(parser_t *parser, ast_block *block, ast_expression **out)
1478 {
1479     ast_loop *aloop;
1480     ast_expression *cond, *ontrue;
1481
1482     lex_ctx ctx = parser_ctx(parser);
1483
1484     /* skip the 'while' and check for opening paren */
1485     if (!parser_next(parser) || parser->tok != '(') {
1486         parseerror(parser, "expected 'while' condition in parenthesis");
1487         return false;
1488     }
1489     /* parse into the expression */
1490     if (!parser_next(parser)) {
1491         parseerror(parser, "expected 'while' condition after opening paren");
1492         return false;
1493     }
1494     /* parse the condition */
1495     cond = parse_expression_leave(parser, false);
1496     if (!cond)
1497         return false;
1498     /* closing paren */
1499     if (parser->tok != ')') {
1500         parseerror(parser, "expected closing paren after 'while' condition");
1501         ast_delete(cond);
1502         return false;
1503     }
1504     /* parse into the 'then' branch */
1505     if (!parser_next(parser)) {
1506         parseerror(parser, "expected while-loop body");
1507         ast_delete(cond);
1508         return false;
1509     }
1510     ontrue = parse_statement_or_block(parser);
1511     if (!ontrue) {
1512         ast_delete(cond);
1513         return false;
1514     }
1515
1516     aloop = ast_loop_new(ctx, NULL, cond, NULL, NULL, ontrue);
1517     *out = (ast_expression*)aloop;
1518     return true;
1519 }
1520
1521 static bool parse_dowhile(parser_t *parser, ast_block *block, ast_expression **out)
1522 {
1523     ast_loop *aloop;
1524     ast_expression *cond, *ontrue;
1525
1526     lex_ctx ctx = parser_ctx(parser);
1527
1528     /* skip the 'do' and get the body */
1529     if (!parser_next(parser)) {
1530         parseerror(parser, "expected loop body");
1531         return false;
1532     }
1533     ontrue = parse_statement_or_block(parser);
1534     if (!ontrue)
1535         return false;
1536
1537     /* expect the "while" */
1538     if (parser->tok != TOKEN_KEYWORD ||
1539         strcmp(parser_tokval(parser), "while"))
1540     {
1541         parseerror(parser, "expected 'while' and condition");
1542         ast_delete(ontrue);
1543         return false;
1544     }
1545
1546     /* skip the 'while' and check for opening paren */
1547     if (!parser_next(parser) || parser->tok != '(') {
1548         parseerror(parser, "expected 'while' condition in parenthesis");
1549         ast_delete(ontrue);
1550         return false;
1551     }
1552     /* parse into the expression */
1553     if (!parser_next(parser)) {
1554         parseerror(parser, "expected 'while' condition after opening paren");
1555         ast_delete(ontrue);
1556         return false;
1557     }
1558     /* parse the condition */
1559     cond = parse_expression_leave(parser, false);
1560     if (!cond)
1561         return false;
1562     /* closing paren */
1563     if (parser->tok != ')') {
1564         parseerror(parser, "expected closing paren after 'while' condition");
1565         ast_delete(ontrue);
1566         ast_delete(cond);
1567         return false;
1568     }
1569     /* parse on */
1570     if (!parser_next(parser) || parser->tok != ';') {
1571         parseerror(parser, "expected semicolon after condition");
1572         ast_delete(ontrue);
1573         ast_delete(cond);
1574         return false;
1575     }
1576
1577     if (!parser_next(parser)) {
1578         parseerror(parser, "parse error");
1579         ast_delete(ontrue);
1580         ast_delete(cond);
1581         return false;
1582     }
1583
1584     aloop = ast_loop_new(ctx, NULL, NULL, cond, NULL, ontrue);
1585     *out = (ast_expression*)aloop;
1586     return true;
1587 }
1588
1589 static bool parse_for(parser_t *parser, ast_block *block, ast_expression **out)
1590 {
1591     ast_loop *aloop;
1592     ast_expression *initexpr, *cond, *increment, *ontrue;
1593     size_t oldblocklocal;
1594     bool   retval = true;
1595
1596     lex_ctx ctx = parser_ctx(parser);
1597
1598     oldblocklocal = parser->blocklocal;
1599     parser->blocklocal = parser->locals_count;
1600
1601     initexpr  = NULL;
1602     cond      = NULL;
1603     increment = NULL;
1604     ontrue    = NULL;
1605
1606     /* skip the 'while' and check for opening paren */
1607     if (!parser_next(parser) || parser->tok != '(') {
1608         parseerror(parser, "expected 'for' expressions in parenthesis");
1609         goto onerr;
1610     }
1611     /* parse into the expression */
1612     if (!parser_next(parser)) {
1613         parseerror(parser, "expected 'for' initializer after opening paren");
1614         goto onerr;
1615     }
1616
1617     if (parser->tok == TOKEN_TYPENAME) {
1618         if (opts_standard != COMPILER_GMQCC) {
1619             if (parsewarning(parser, WARN_EXTENSIONS,
1620                              "current standard does not allow variable declarations in for-loop initializers"))
1621                 goto onerr;
1622         }
1623
1624         parseerror(parser, "TODO: assignment of new variables to be non-const");
1625         goto onerr;
1626         if (!parse_variable(parser, block))
1627             goto onerr;
1628     }
1629     else if (parser->tok != ';')
1630     {
1631         initexpr = parse_expression_leave(parser, false);
1632         if (!initexpr)
1633             goto onerr;
1634     }
1635
1636     /* move on to condition */
1637     if (parser->tok != ';') {
1638         parseerror(parser, "expected semicolon after for-loop initializer");
1639         goto onerr;
1640     }
1641     if (!parser_next(parser)) {
1642         parseerror(parser, "expected for-loop condition");
1643         goto onerr;
1644     }
1645
1646     /* parse the condition */
1647     if (parser->tok != ';') {
1648         cond = parse_expression_leave(parser, false);
1649         if (!cond)
1650             goto onerr;
1651     }
1652
1653     /* move on to incrementor */
1654     if (parser->tok != ';') {
1655         parseerror(parser, "expected semicolon after for-loop initializer");
1656         goto onerr;
1657     }
1658     if (!parser_next(parser)) {
1659         parseerror(parser, "expected for-loop condition");
1660         goto onerr;
1661     }
1662
1663     /* parse the incrementor */
1664     if (parser->tok != ')') {
1665         increment = parse_expression_leave(parser, false);
1666         if (!increment)
1667             goto onerr;
1668         if (!ast_istype(increment, ast_store) &&
1669             !ast_istype(increment, ast_call) &&
1670             !ast_istype(increment, ast_binstore))
1671         {
1672             if (genwarning(ast_ctx(increment), WARN_EFFECTLESS_STATEMENT, "statement has no effect"))
1673                 goto onerr;
1674         }
1675     }
1676
1677     /* closing paren */
1678     if (parser->tok != ')') {
1679         parseerror(parser, "expected closing paren after 'for-loop' incrementor");
1680         goto onerr;
1681     }
1682     /* parse into the 'then' branch */
1683     if (!parser_next(parser)) {
1684         parseerror(parser, "expected for-loop body");
1685         goto onerr;
1686     }
1687     ontrue = parse_statement_or_block(parser);
1688     if (!ontrue) {
1689         goto onerr;
1690     }
1691
1692     aloop = ast_loop_new(ctx, initexpr, cond, NULL, increment, ontrue);
1693     *out = (ast_expression*)aloop;
1694
1695     while (parser->locals_count > parser->blocklocal)
1696         retval = retval && parser_pop_local(parser);
1697     parser->blocklocal = oldblocklocal;
1698     return retval;
1699 onerr:
1700     if (initexpr)  ast_delete(initexpr);
1701     if (cond)      ast_delete(cond);
1702     if (increment) ast_delete(increment);
1703     while (parser->locals_count > parser->blocklocal)
1704         (void)!parser_pop_local(parser);
1705     parser->blocklocal = oldblocklocal;
1706     return false;
1707 }
1708
1709 static bool parse_statement(parser_t *parser, ast_block *block, ast_expression **out)
1710 {
1711     if (parser->tok == TOKEN_TYPENAME)
1712     {
1713         /* local variable */
1714         if (!block) {
1715             parseerror(parser, "cannot declare a variable from here");
1716             return false;
1717         }
1718         if (opts_standard == COMPILER_QCC) {
1719             if (parsewarning(parser, WARN_EXTENSIONS, "missing 'local' keyword when declaring a local variable"))
1720                 return false;
1721         }
1722         if (!parse_variable(parser, block))
1723             return false;
1724         *out = NULL;
1725         return true;
1726     }
1727     else if (parser->tok == TOKEN_KEYWORD)
1728     {
1729         if (!strcmp(parser_tokval(parser), "local"))
1730         {
1731             if (!block) {
1732                 parseerror(parser, "cannot declare a local variable here");
1733                 return false;
1734             }
1735             if (!parser_next(parser)) {
1736                 parseerror(parser, "expected variable declaration");
1737                 return false;
1738             }
1739             if (!parse_variable(parser, block))
1740                 return false;
1741             *out = NULL;
1742             return true;
1743         }
1744         else if (!strcmp(parser_tokval(parser), "return"))
1745         {
1746             ast_expression *exp = NULL;
1747             ast_return     *ret = NULL;
1748             ast_value      *expected = parser->function->vtype;
1749
1750             if (!parser_next(parser)) {
1751                 parseerror(parser, "expected return expression");
1752                 return false;
1753             }
1754
1755             if (parser->tok != ';') {
1756                 exp = parse_expression(parser, false);
1757                 if (!exp)
1758                     return false;
1759
1760                 if (exp->expression.vtype != expected->expression.next->expression.vtype) {
1761                     parseerror(parser, "return with invalid expression");
1762                 }
1763
1764                 ret = ast_return_new(exp->expression.node.context, exp);
1765                 if (!ret) {
1766                     ast_delete(exp);
1767                     return false;
1768                 }
1769             } else {
1770                 if (!parser_next(parser))
1771                     parseerror(parser, "parse error");
1772                 if (expected->expression.next->expression.vtype != TYPE_VOID) {
1773                     if (opts_standard != COMPILER_GMQCC)
1774                         (void)!parsewarning(parser, WARN_MISSING_RETURN_VALUES, "return without value");
1775                     else
1776                         parseerror(parser, "return without value");
1777                 }
1778                 ret = ast_return_new(parser_ctx(parser), NULL);
1779             }
1780             *out = (ast_expression*)ret;
1781             return true;
1782         }
1783         else if (!strcmp(parser_tokval(parser), "if"))
1784         {
1785             return parse_if(parser, block, out);
1786         }
1787         else if (!strcmp(parser_tokval(parser), "while"))
1788         {
1789             return parse_while(parser, block, out);
1790         }
1791         else if (!strcmp(parser_tokval(parser), "do"))
1792         {
1793             return parse_dowhile(parser, block, out);
1794         }
1795         else if (!strcmp(parser_tokval(parser), "for"))
1796         {
1797             if (opts_standard == COMPILER_QCC) {
1798                 if (parsewarning(parser, WARN_EXTENSIONS, "for loops are not recognized in the original Quake C standard, to enable try an alternate standard --std=?"))
1799                     return false;
1800             }
1801             return parse_for(parser, block, out);
1802         }
1803         parseerror(parser, "Unexpected keyword");
1804         return false;
1805     }
1806     else if (parser->tok == '{')
1807     {
1808         ast_block *inner;
1809         inner = parse_block(parser, false);
1810         if (!inner)
1811             return false;
1812         *out = (ast_expression*)inner;
1813         return true;
1814     }
1815     else
1816     {
1817         ast_expression *exp = parse_expression(parser, false);
1818         if (!exp)
1819             return false;
1820         *out = exp;
1821         if (!ast_istype(exp, ast_store) &&
1822             !ast_istype(exp, ast_call) &&
1823             !ast_istype(exp, ast_binstore))
1824         {
1825             if (genwarning(ast_ctx(exp), WARN_EFFECTLESS_STATEMENT, "statement has no effect"))
1826                 return false;
1827         }
1828         return true;
1829     }
1830 }
1831
1832 static bool GMQCC_WARN parser_pop_local(parser_t *parser)
1833 {
1834     varentry_t *ve;
1835     parser->locals_count--;
1836
1837     ve = &parser->locals[parser->locals_count];
1838     if (ast_istype(ve->var, ast_value) && !(((ast_value*)(ve->var))->uses)) {
1839         if (parsewarning(parser, WARN_UNUSED_VARIABLE, "unused variable: `%s`", ve->name))
1840             return false;
1841     }
1842     mem_d(parser->locals[parser->locals_count].name);
1843     return true;
1844 }
1845
1846 static bool parse_block_into(parser_t *parser, ast_block *block, bool warnreturn)
1847 {
1848     size_t oldblocklocal;
1849     bool   retval = true;
1850
1851     oldblocklocal = parser->blocklocal;
1852     parser->blocklocal = parser->locals_count;
1853
1854     if (!parser_next(parser)) { /* skip the '{' */
1855         parseerror(parser, "expected function body");
1856         goto cleanup;
1857     }
1858
1859     while (parser->tok != TOKEN_EOF && parser->tok < TOKEN_ERROR)
1860     {
1861         ast_expression *expr;
1862         if (parser->tok == '}')
1863             break;
1864
1865         if (!parse_statement(parser, block, &expr)) {
1866             /* parseerror(parser, "parse error"); */
1867             block = NULL;
1868             goto cleanup;
1869         }
1870         if (!expr)
1871             continue;
1872         if (!ast_block_exprs_add(block, expr)) {
1873             ast_delete(expr);
1874             block = NULL;
1875             goto cleanup;
1876         }
1877     }
1878
1879     if (parser->tok != '}') {
1880         block = NULL;
1881     } else {
1882         if (warnreturn && parser->function->vtype->expression.next->expression.vtype != TYPE_VOID)
1883         {
1884             if (!block->exprs_count ||
1885                 !ast_istype(block->exprs[block->exprs_count-1], ast_return))
1886             {
1887                 if (parsewarning(parser, WARN_MISSING_RETURN_VALUES, "control reaches end of non-void function")) {
1888                     block = NULL;
1889                     goto cleanup;
1890                 }
1891             }
1892         }
1893         (void)parser_next(parser);
1894     }
1895
1896 cleanup:
1897     while (parser->locals_count > parser->blocklocal)
1898         retval = retval && parser_pop_local(parser);
1899     parser->blocklocal = oldblocklocal;
1900     return !!block;
1901 }
1902
1903 static ast_block* parse_block(parser_t *parser, bool warnreturn)
1904 {
1905     ast_block *block;
1906     block = ast_block_new(parser_ctx(parser));
1907     if (!block)
1908         return NULL;
1909     if (!parse_block_into(parser, block, warnreturn)) {
1910         ast_block_delete(block);
1911         return NULL;
1912     }
1913     return block;
1914 }
1915
1916 static ast_expression* parse_statement_or_block(parser_t *parser)
1917 {
1918     ast_expression *expr = NULL;
1919     if (parser->tok == '{')
1920         return (ast_expression*)parse_block(parser, false);
1921     if (!parse_statement(parser, NULL, &expr))
1922         return NULL;
1923     return expr;
1924 }
1925
1926 /* loop method */
1927 static bool create_vector_members(parser_t *parser, ast_value *var, varentry_t *ve)
1928 {
1929     size_t i;
1930     size_t len = strlen(var->name);
1931
1932     for (i = 0; i < 3; ++i) {
1933         ve[i].var = (ast_expression*)ast_member_new(ast_ctx(var), (ast_expression*)var, i);
1934         if (!ve[i].var)
1935             break;
1936
1937         ve[i].name = (char*)mem_a(len+3);
1938         if (!ve[i].name) {
1939             ast_delete(ve[i].var);
1940             break;
1941         }
1942
1943         memcpy(ve[i].name, var->name, len);
1944         ve[i].name[len]   = '_';
1945         ve[i].name[len+1] = 'x'+i;
1946         ve[i].name[len+2] = 0;
1947     }
1948     if (i == 3)
1949         return true;
1950
1951     /* unroll */
1952     do {
1953         --i;
1954         mem_d(ve[i].name);
1955         ast_delete(ve[i].var);
1956         ve[i].name = NULL;
1957         ve[i].var  = NULL;
1958     } while (i);
1959     return false;
1960 }
1961
1962 static bool parse_function_body(parser_t *parser, ast_value *var)
1963 {
1964     ast_block      *block = NULL;
1965     ast_function   *func;
1966     ast_function   *old;
1967     size_t          parami;
1968
1969     ast_expression *framenum  = NULL;
1970     ast_expression *nextthink = NULL;
1971     /* None of the following have to be deleted */
1972     ast_expression *fld_think = NULL, *fld_nextthink = NULL, *fld_frame = NULL;
1973     ast_expression *gbl_time = NULL, *gbl_self = NULL;
1974     bool            has_frame_think;
1975
1976     bool retval = true;
1977
1978     has_frame_think = false;
1979     old = parser->function;
1980
1981     if (var->expression.variadic) {
1982         if (parsewarning(parser, WARN_VARIADIC_FUNCTION,
1983                          "variadic function with implementation will not be able to access additional parameters"))
1984         {
1985             return false;
1986         }
1987     }
1988
1989     if (parser->tok == '[') {
1990         /* got a frame definition: [ framenum, nextthink ]
1991          * this translates to:
1992          * self.frame = framenum;
1993          * self.nextthink = time + 0.1;
1994          * self.think = nextthink;
1995          */
1996         nextthink = NULL;
1997
1998         fld_think     = parser_find_field(parser, "think");
1999         fld_nextthink = parser_find_field(parser, "nextthink");
2000         fld_frame     = parser_find_field(parser, "frame");
2001         if (!fld_think || !fld_nextthink || !fld_frame) {
2002             parseerror(parser, "cannot use [frame,think] notation without the required fields");
2003             parseerror(parser, "please declare the following entityfields: `frame`, `think`, `nextthink`");
2004             return false;
2005         }
2006         gbl_time      = parser_find_global(parser, "time");
2007         gbl_self      = parser_find_global(parser, "self");
2008         if (!gbl_time || !gbl_self) {
2009             parseerror(parser, "cannot use [frame,think] notation without the required globals");
2010             parseerror(parser, "please declare the following globals: `time`, `self`");
2011             return false;
2012         }
2013
2014         if (!parser_next(parser))
2015             return false;
2016
2017         framenum = parse_expression_leave(parser, true);
2018         if (!framenum) {
2019             parseerror(parser, "expected a framenumber constant in[frame,think] notation");
2020             return false;
2021         }
2022         if (!ast_istype(framenum, ast_value) || !( (ast_value*)framenum )->isconst) {
2023             ast_unref(framenum);
2024             parseerror(parser, "framenumber in [frame,think] notation must be a constant");
2025             return false;
2026         }
2027
2028         if (parser->tok != ',') {
2029             ast_unref(framenum);
2030             parseerror(parser, "expected comma after frame number in [frame,think] notation");
2031             parseerror(parser, "Got a %i\n", parser->tok);
2032             return false;
2033         }
2034
2035         if (!parser_next(parser)) {
2036             ast_unref(framenum);
2037             return false;
2038         }
2039
2040         if (parser->tok == TOKEN_IDENT && !parser_find_var(parser, parser_tokval(parser)))
2041         {
2042             /* qc allows the use of not-yet-declared functions here
2043              * - this automatically creates a prototype */
2044             varentry_t      varent;
2045             ast_value      *thinkfunc;
2046             ast_expression *functype = fld_think->expression.next;
2047
2048             thinkfunc = ast_value_new(parser_ctx(parser), parser_tokval(parser), functype->expression.vtype);
2049             if (!thinkfunc || !ast_type_adopt(thinkfunc, functype)) {
2050                 ast_unref(framenum);
2051                 parseerror(parser, "failed to create implicit prototype for `%s`", parser_tokval(parser));
2052                 return false;
2053             }
2054
2055             if (!parser_next(parser)) {
2056                 ast_unref(framenum);
2057                 ast_delete(thinkfunc);
2058                 return false;
2059             }
2060
2061             varent.var = (ast_expression*)thinkfunc;
2062             varent.name = util_strdup(thinkfunc->name);
2063             if (!parser_t_globals_add(parser, varent)) {
2064                 ast_unref(framenum);
2065                 ast_delete(thinkfunc);
2066                 return false;
2067             }
2068             nextthink = (ast_expression*)thinkfunc;
2069
2070         } else {
2071             nextthink = parse_expression_leave(parser, true);
2072             if (!nextthink) {
2073                 ast_unref(framenum);
2074                 parseerror(parser, "expected a think-function in [frame,think] notation");
2075                 return false;
2076             }
2077         }
2078
2079         if (!ast_istype(nextthink, ast_value)) {
2080             parseerror(parser, "think-function in [frame,think] notation must be a constant");
2081             retval = false;
2082         }
2083
2084         if (retval && parser->tok != ']') {
2085             parseerror(parser, "expected closing `]` for [frame,think] notation");
2086             retval = false;
2087         }
2088
2089         if (retval && !parser_next(parser)) {
2090             retval = false;
2091         }
2092
2093         if (retval && parser->tok != '{') {
2094             parseerror(parser, "a function body has to be declared after a [frame,think] declaration");
2095             retval = false;
2096         }
2097
2098         if (!retval) {
2099             ast_unref(nextthink);
2100             ast_unref(framenum);
2101             return false;
2102         }
2103
2104         has_frame_think = true;
2105     }
2106
2107     block = ast_block_new(parser_ctx(parser));
2108     if (!block) {
2109         parseerror(parser, "failed to allocate block");
2110         if (has_frame_think) {
2111             ast_unref(nextthink);
2112             ast_unref(framenum);
2113         }
2114         return false;
2115     }
2116
2117     if (has_frame_think) {
2118         lex_ctx ctx;
2119         ast_expression *self_frame;
2120         ast_expression *self_nextthink;
2121         ast_expression *self_think;
2122         ast_expression *time_plus_1;
2123         ast_store *store_frame;
2124         ast_store *store_nextthink;
2125         ast_store *store_think;
2126
2127         ctx = parser_ctx(parser);
2128         self_frame     = (ast_expression*)ast_entfield_new(ctx, gbl_self, fld_frame);
2129         self_nextthink = (ast_expression*)ast_entfield_new(ctx, gbl_self, fld_nextthink);
2130         self_think     = (ast_expression*)ast_entfield_new(ctx, gbl_self, fld_think);
2131
2132         time_plus_1    = (ast_expression*)ast_binary_new(ctx, INSTR_ADD_F,
2133                          gbl_time, (ast_expression*)parser_const_float(parser, 0.1));
2134
2135         if (!self_frame || !self_nextthink || !self_think || !time_plus_1) {
2136             if (self_frame)     ast_delete(self_frame);
2137             if (self_nextthink) ast_delete(self_nextthink);
2138             if (self_think)     ast_delete(self_think);
2139             if (time_plus_1)    ast_delete(time_plus_1);
2140             retval = false;
2141         }
2142
2143         if (retval)
2144         {
2145             store_frame     = ast_store_new(ctx, INSTR_STOREP_F,   self_frame,     framenum);
2146             store_nextthink = ast_store_new(ctx, INSTR_STOREP_F,   self_nextthink, time_plus_1);
2147             store_think     = ast_store_new(ctx, INSTR_STOREP_FNC, self_think,     nextthink);
2148
2149             if (!store_frame) {
2150                 ast_delete(self_frame);
2151                 retval = false;
2152             }
2153             if (!store_nextthink) {
2154                 ast_delete(self_nextthink);
2155                 retval = false;
2156             }
2157             if (!store_think) {
2158                 ast_delete(self_think);
2159                 retval = false;
2160             }
2161             if (!retval) {
2162                 if (store_frame)     ast_delete(store_frame);
2163                 if (store_nextthink) ast_delete(store_nextthink);
2164                 if (store_think)     ast_delete(store_think);
2165                 retval = false;
2166             }
2167             if (retval && !ast_block_exprs_add(block, (ast_expression*)store_frame)) {
2168                 ast_delete(store_frame);
2169                 ast_delete(store_nextthink);
2170                 ast_delete(store_think);
2171                 retval = false;
2172             }
2173
2174             if (retval && !ast_block_exprs_add(block, (ast_expression*)store_nextthink)) {
2175                 ast_delete(store_nextthink);
2176                 ast_delete(store_think);
2177                 retval = false;
2178             }
2179
2180             if (retval && !ast_block_exprs_add(block, (ast_expression*)store_think) )
2181             {
2182                 ast_delete(store_think);
2183                 retval = false;
2184             }
2185         }
2186
2187         if (!retval) {
2188             parseerror(parser, "failed to generate code for [frame,think]");
2189             ast_unref(nextthink);
2190             ast_unref(framenum);
2191             ast_delete(block);
2192             return false;
2193         }
2194     }
2195
2196     for (parami = 0; parami < var->expression.params_count; ++parami) {
2197         size_t     e;
2198         varentry_t ve[3];
2199         ast_value *param = var->expression.params[parami];
2200
2201         if (param->expression.vtype != TYPE_VECTOR &&
2202             (param->expression.vtype != TYPE_FIELD ||
2203              param->expression.next->expression.vtype != TYPE_VECTOR))
2204         {
2205             continue;
2206         }
2207
2208         if (!create_vector_members(parser, param, ve)) {
2209             ast_block_delete(block);
2210             return false;
2211         }
2212
2213         for (e = 0; e < 3; ++e) {
2214             if (!parser_t_locals_add(parser, ve[e]))
2215                 break;
2216             if (!ast_block_collect(block, ve[e].var)) {
2217                 parser->locals_count--;
2218                 break;
2219             }
2220             ve[e].var = NULL; /* collected */
2221         }
2222         if (e != 3) {
2223             parser->locals -= e;
2224             do {
2225                 mem_d(ve[e].name);
2226                 --e;
2227             } while (e);
2228             ast_block_delete(block);
2229             return false;
2230         }
2231     }
2232
2233     func = ast_function_new(ast_ctx(var), var->name, var);
2234     if (!func) {
2235         parseerror(parser, "failed to allocate function for `%s`", var->name);
2236         ast_block_delete(block);
2237         goto enderr;
2238     }
2239     if (!parser_t_functions_add(parser, func)) {
2240         parseerror(parser, "failed to allocate slot for function `%s`", var->name);
2241         ast_block_delete(block);
2242         goto enderrfn;
2243     }
2244
2245     parser->function = func;
2246     if (!parse_block_into(parser, block, true)) {
2247         ast_block_delete(block);
2248         goto enderrfn2;
2249     }
2250
2251     if (!ast_function_blocks_add(func, block)) {
2252         ast_block_delete(block);
2253         goto enderrfn2;
2254     }
2255
2256     parser->function = old;
2257     while (parser->locals_count)
2258         retval = retval && parser_pop_local(parser);
2259
2260     if (parser->tok == ';')
2261         return parser_next(parser);
2262     else if (opts_standard == COMPILER_QCC)
2263         parseerror(parser, "missing semicolon after function body (mandatory with -std=qcc)");
2264     return retval;
2265
2266 enderrfn2:
2267     parser->functions_count--;
2268 enderrfn:
2269     ast_function_delete(func);
2270     var->constval.vfunc = NULL;
2271
2272 enderr:
2273     while (parser->locals_count) {
2274         parser->locals_count--;
2275         mem_d(parser->locals[parser->locals_count].name);
2276     }
2277     parser->function = old;
2278     return false;
2279 }
2280
2281 static bool parse_variable(parser_t *parser, ast_block *localblock)
2282 {
2283     bool            isfunc = false;
2284     lex_ctx         ctx;
2285
2286     ast_value      *var = NULL;
2287     ast_value      *fld = NULL;
2288     bool cleanvar = false;
2289
2290     varentry_t      varent;
2291     varentry_t      ve[3];
2292
2293     ast_expression *olddecl;
2294
2295     ast_value      *typevar;
2296
2297     bool hadproto;
2298     bool isparam;
2299
2300     bool retval = true;
2301     bool isfield = false;
2302
2303     /* go */
2304
2305     int basetype;
2306
2307     if (parser->tok == '.') {
2308         isfield = true;
2309         if (!parser_next(parser)) {
2310             parseerror(parser, "expected typename for field definition");
2311             return false;
2312         }
2313     }
2314
2315     basetype = parser_token(parser)->constval.t;
2316
2317     if (!parser_next(parser)) {
2318         parseerror(parser, "expected variable definition");
2319         return false;
2320     }
2321
2322     typevar = parse_type(parser, basetype, &isfunc);
2323     if (!typevar)
2324         return false;
2325
2326     while (true)
2327     {
2328         hadproto    = false;
2329         olddecl     = NULL;
2330         isparam     = false;
2331         varent.name = NULL;
2332
2333         ve[0].name = ve[1].name = ve[2].name = NULL;
2334         ve[0].var  = ve[1].var  = ve[2].var  = NULL;
2335
2336         ctx = parser_ctx(parser);
2337         var = ast_value_copy(typevar);
2338         cleanvar = true;
2339
2340         if (!var) {
2341             parseerror(parser, "failed to create variable");
2342             retval = false;
2343             goto cleanup;
2344         }
2345
2346         if (parser->tok != TOKEN_IDENT) {
2347             parseerror(parser, "expected variable name");
2348             retval = false;
2349             goto cleanup;
2350         }
2351
2352         if (!localblock) {
2353             bool was_end = false;
2354             if      (!strcmp(parser_tokval(parser), "end_sys_globals")) {
2355                 parser->crc_globals = parser->globals_count;
2356                 was_end = true;
2357             }
2358             else if (!strcmp(parser_tokval(parser), "end_sys_fields")) {
2359                 parser->crc_fields = parser->fields_count;
2360                 was_end = true;
2361             }
2362             if (isfield && was_end) {
2363                 if (parsewarning(parser, WARN_END_SYS_FIELDS,
2364                                  "global '%s' hint should not be a field",
2365                                  parser_tokval(parser)))
2366                 {
2367                     retval = false;
2368                     goto cleanup;
2369                 }
2370
2371             }
2372         }
2373
2374         if (!ast_value_set_name(var, parser_tokval(parser))) {
2375             parseerror(parser, "failed to set variable name\n");
2376             retval = false;
2377             goto cleanup;
2378         }
2379
2380         if (isfunc) {
2381             /* a function was defined */
2382             ast_value *fval;
2383             ast_value *proto = NULL;
2384             bool dummy;
2385
2386             if (!localblock)
2387                 olddecl = parser_find_global(parser, parser_tokval(parser));
2388             else
2389                 olddecl = parser_find_local(parser, parser_tokval(parser), parser->blocklocal, &dummy);
2390
2391             if (olddecl) {
2392                 /* we had a prototype */
2393                 if (!ast_istype(olddecl, ast_value)) {
2394                     /* vector v;
2395                      * void() v_x = {}
2396                      */
2397                     parseerror(parser, "cannot declare a function with the same name as a vector's member: %s",
2398                                parser_tokval(parser));
2399                     retval = false;
2400                     goto cleanup;
2401                 }
2402
2403                 proto = (ast_value*)olddecl;
2404             }
2405
2406             /* turn var into a value of TYPE_FUNCTION, with the old var
2407              * as return type
2408              */
2409             fval = ast_value_new(ctx, var->name, TYPE_FUNCTION);
2410             if (!fval) {
2411                 retval = false;
2412                 goto cleanup;
2413             }
2414
2415             fval->expression.next = (ast_expression*)var;
2416             MEM_VECTOR_MOVE(&var->expression, params, &fval->expression, params);
2417             fval->expression.variadic = var->expression.variadic;
2418             var = NULL;
2419
2420             /* we compare the type late here, but it's easier than
2421              * messing with the parameter-vector etc. earlier
2422              */
2423             if (proto) {
2424                 size_t param;
2425                 if (!ast_compare_type((ast_expression*)proto, (ast_expression*)fval)) {
2426                     parseerror(parser, "conflicting types for `%s`, previous declaration was here: %s:%i",
2427                                proto->name,
2428                                ast_ctx(proto).file, ast_ctx(proto).line);
2429                     ast_value_delete(fval);
2430                     retval = false;
2431                     goto cleanup;
2432                 }
2433                 /* copy over the parameter names */
2434                 for (param = 0; param < fval->expression.params_count; ++param)
2435                     ast_value_set_name(proto->expression.params[param], fval->expression.params[param]->name);
2436                 /* copy the new context */
2437                 ast_ctx(proto) = ast_ctx(fval);
2438
2439                 /* now ditch the rest of the new data */
2440                 ast_value_delete(fval);
2441                 fval = proto;
2442                 hadproto = true;
2443             }
2444
2445             var = fval;
2446         }
2447
2448         if (isfield) {
2449             ast_value *tmp;
2450             fld = ast_value_new(ctx, var->name, TYPE_FIELD);
2451             fld->expression.next = (ast_expression*)var;
2452             tmp = var;
2453             var = fld;
2454             fld = tmp;
2455         }
2456         else
2457             fld = var;
2458
2459         if (!isfunc) {
2460             if (!localblock)
2461             {
2462                 olddecl = parser_find_global(parser, var->name);
2463                 if (olddecl) {
2464                     if (!isfield) {
2465                         parseerror(parser, "global `%s` already declared here: %s:%i",
2466                                    var->name, ast_ctx(olddecl).file, (int)ast_ctx(olddecl).line);
2467                         retval = false;
2468                         goto cleanup;
2469                     }
2470                     else if (opts_standard == COMPILER_QCC) {
2471                         parseerror(parser, "cannot declare a field and a global of the same name with -std=qcc");
2472                         parseerror(parser, "global `%s` already declared here: %s:%i",
2473                                    var->name, ast_ctx(olddecl).file, (int)ast_ctx(olddecl).line);
2474                         retval = false;
2475                         goto cleanup;
2476                     }
2477                 }
2478                 olddecl = parser_find_field(parser, var->name);
2479                 if (olddecl && opts_standard == COMPILER_QCC) {
2480                     if (!isfield) {
2481                         parseerror(parser, "cannot declare a field and a global of the same name with -std=qcc");
2482                         parseerror(parser, "field `%s` already declared here: %s:%i",
2483                                    var->name, ast_ctx(olddecl).file, (int)ast_ctx(olddecl).line);
2484                         retval = false;
2485                         goto cleanup;
2486                     }
2487                     else
2488                     {
2489                         if (parsewarning(parser, WARN_FIELD_REDECLARED, "field `%s` already declared here: %s:%i",
2490                                          var->name, ast_ctx(olddecl).file, (int)ast_ctx(olddecl).line))
2491                         {
2492                             retval = false;
2493                             goto cleanup;
2494                         }
2495                         if (!ast_compare_type(olddecl, (ast_expression*)var)) {
2496                             parseerror(parser, "field %s has previously been declared with a different type here: %s:%i",
2497                                        var->name, ast_ctx(olddecl).file, (int)ast_ctx(olddecl).line);
2498                             retval = false;
2499                             goto cleanup;
2500                         }
2501                         ast_delete(var);
2502                         var = NULL;
2503                         goto nextvar;
2504                     }
2505                 }
2506                 else if (olddecl) {
2507                     parseerror(parser, "field `%s` already declared here: %s:%i",
2508                                var->name, ast_ctx(olddecl).file, (int)ast_ctx(olddecl).line);
2509                     retval = false;
2510                     goto cleanup;
2511                 }
2512             }
2513             else /* if it's a local: */
2514             {
2515                 olddecl = parser_find_local(parser, var->name, parser->blocklocal, &isparam);
2516                 if (opts_standard == COMPILER_GMQCC)
2517                 {
2518                     if (olddecl)
2519                     {
2520                         if (!isparam) {
2521                             parseerror(parser, "local `%s` already declared here: %s:%i",
2522                                        var->name, ast_ctx(olddecl).file, (int)ast_ctx(olddecl).line);
2523                             retval = false;
2524                             goto cleanup;
2525                         }
2526                     }
2527
2528                     if( (!isparam && olddecl) ||
2529                         (olddecl = parser_find_local(parser, var->name, 0, &isparam))
2530                       )
2531                     {
2532                         if (parsewarning(parser, WARN_LOCAL_SHADOWS,
2533                                          "local `%s` is shadowing a parameter", var->name))
2534                         {
2535                             parseerror(parser, "local `%s` already declared here: %s:%i",
2536                                        var->name, ast_ctx(olddecl).file, (int)ast_ctx(olddecl).line);
2537                             retval = false;
2538                             goto cleanup;
2539                         }
2540                     }
2541                 }
2542                 else
2543                 {
2544                     if (olddecl)
2545                     {
2546                         if (isparam &&
2547                             parsewarning(parser, WARN_LOCAL_SHADOWS,
2548                                          "a parameter is shadowing local `%s`", var->name))
2549                         {
2550                             ast_value_delete(var);
2551                             var = NULL;
2552                             retval = false;
2553                             goto cleanup;
2554                         }
2555                         else if (!isparam)
2556                         {
2557                             parseerror(parser, "local `%s` already declared here: %s:%i",
2558                                        var->name, ast_ctx(olddecl).file, (int)ast_ctx(olddecl).line);
2559                             ast_value_delete(var);
2560                             var = NULL;
2561                             retval = false;
2562                             goto cleanup;
2563                         }
2564                         ast_value_delete(var);
2565                         var = NULL;
2566                         goto nextvar;
2567                     }
2568                 }
2569             }
2570         }
2571
2572
2573         if (!hadproto) {
2574             varent.name = util_strdup(var->name);
2575             varent.var = (ast_expression*)var;
2576
2577             if (!localblock) {
2578                 if (!isfield) {
2579                     if (!(retval = parser_t_globals_add(parser, varent)))
2580                         goto cleanup;
2581                 }
2582                 else {
2583                     if (!(retval = parser_t_fields_add(parser, varent)))
2584                         goto cleanup;
2585                 }
2586             } else {
2587                 if (!(retval = parser_t_locals_add(parser, varent)))
2588                     goto cleanup;
2589                 if (!(retval = ast_block_locals_add(localblock, var))) {
2590                     parser->locals_count--;
2591                     goto cleanup;
2592                 }
2593             }
2594
2595             if (fld->expression.vtype == TYPE_VECTOR)
2596             {
2597                 size_t e;
2598                 if (!create_vector_members(parser, var, ve)) {
2599                     retval = false;
2600                     goto cleanup;
2601                 }
2602
2603                 if (!localblock) {
2604                     for (e = 0; e < 3; ++e) {
2605                         if (!isfield) {
2606                             if (!(retval = parser_t_globals_add(parser, ve[e])))
2607                                 break;
2608                         }
2609                         else {
2610                             if (!(retval = parser_t_fields_add(parser, ve[e])))
2611                                 break;
2612                         }
2613                     }
2614                     if (!retval) {
2615                         parser->globals_count -= e+1;
2616                         goto cleanup;
2617                     }
2618                 } else {
2619                     for (e = 0; e < 3; ++e) {
2620                         if (!(retval = parser_t_locals_add(parser, ve[e])))
2621                             break;
2622                         if (!(retval = ast_block_collect(localblock, ve[e].var)))
2623                             break;
2624                         ve[e].var = NULL; /* from here it's being collected in the block */
2625                     }
2626                     if (!retval) {
2627                         parser->locals_count -= e+1;
2628                         localblock->locals_count--;
2629                         goto cleanup;
2630                     }
2631                 }
2632                 ve[0].name = ve[1].name = ve[2].name = NULL;
2633                 ve[0].var  = ve[1].var  = ve[2].var  = NULL;
2634             }
2635             cleanvar = false;
2636             varent.name = NULL;
2637         }
2638
2639 nextvar:
2640         if (!(retval = parser_next(parser)))
2641             goto cleanup;
2642
2643         if (parser->tok == ';') {
2644             ast_value_delete(typevar);
2645             return parser_next(parser);
2646         }
2647
2648         if (parser->tok == ',') {
2649             /* another var */
2650             if (!(retval = parser_next(parser)))
2651                 goto cleanup;
2652             continue;
2653         }
2654
2655         if (!localblock && isfield) {
2656             parseerror(parser, "missing semicolon");
2657             ast_value_delete(typevar);
2658             return false;
2659         }
2660
2661         /* NOTE: only 'typevar' needs to be deleted from here on, so 'cleanup' won't be used
2662          * to avoid having too many gotos
2663          */
2664         if (localblock && opts_standard == COMPILER_QCC) {
2665             if (parsewarning(parser, WARN_LOCAL_CONSTANTS,
2666                              "initializing expression turns variable `%s` into a constant in this standard",
2667                              var->name) )
2668             {
2669                 ast_value_delete(typevar);
2670                 return false;
2671             }
2672         }
2673
2674         if (parser->tok != '=') {
2675             if (opts_standard == COMPILER_QCC)
2676                 parseerror(parser, "missing semicolon");
2677             else
2678                 parseerror(parser, "missing semicolon or initializer");
2679             ast_value_delete(typevar);
2680             return false;
2681         }
2682
2683         if (!parser_next(parser)) {
2684             ast_value_delete(typevar);
2685             return false;
2686         }
2687
2688         if (parser->tok == '#') {
2689             ast_function *func;
2690
2691             if (localblock) {
2692                 parseerror(parser, "cannot declare builtins within functions");
2693                 ast_value_delete(typevar);
2694                 return false;
2695             }
2696             if (!isfunc) {
2697                 parseerror(parser, "unexpected builtin number, '%s' is not a function", var->name);
2698                 ast_value_delete(typevar);
2699                 return false;
2700             }
2701             if (!parser_next(parser)) {
2702                 parseerror(parser, "expected builtin number");
2703                 ast_value_delete(typevar);
2704                 return false;
2705             }
2706             if (parser->tok != TOKEN_INTCONST) {
2707                 parseerror(parser, "builtin number must be an integer constant");
2708                 ast_value_delete(typevar);
2709                 return false;
2710             }
2711             if (parser_token(parser)->constval.i <= 0) {
2712                 parseerror(parser, "builtin number must be positive integer greater than zero");
2713                 ast_value_delete(typevar);
2714                 return false;
2715             }
2716
2717             func = ast_function_new(ast_ctx(var), var->name, var);
2718             if (!func) {
2719                 parseerror(parser, "failed to allocate function for `%s`", var->name);
2720                 ast_value_delete(typevar);
2721                 return false;
2722             }
2723             if (!parser_t_functions_add(parser, func)) {
2724                 parseerror(parser, "failed to allocate slot for function `%s`", var->name);
2725                 ast_function_delete(func);
2726                 var->constval.vfunc = NULL;
2727                 ast_value_delete(typevar);
2728                 return false;
2729             }
2730
2731             func->builtin = -parser_token(parser)->constval.i;
2732
2733             if (!parser_next(parser)) {
2734                 ast_value_delete(typevar);
2735                 return false;
2736             }
2737         }
2738         else if (parser->tok == '{' || parser->tok == '[')
2739         {
2740             ast_value_delete(typevar);
2741             if (localblock) {
2742                 parseerror(parser, "cannot declare functions within functions");
2743                 return false;
2744             }
2745
2746             if (!parse_function_body(parser, var)) {
2747                 return false;
2748             }
2749             return true;
2750         } else {
2751             ast_expression *cexp;
2752             ast_value      *cval;
2753
2754             cexp = parse_expression_leave(parser, true);
2755             if (!cexp) {
2756                 ast_value_delete(typevar);
2757                 return false;
2758             }
2759
2760             cval = (ast_value*)cexp;
2761             if (!ast_istype(cval, ast_value) || !cval->isconst)
2762                 parseerror(parser, "cannot initialize a global constant variable with a non-constant expression");
2763             else
2764             {
2765                 var->isconst = true;
2766                 if (cval->expression.vtype == TYPE_STRING)
2767                     var->constval.vstring = parser_strdup(cval->constval.vstring);
2768                 else
2769                     memcpy(&var->constval, &cval->constval, sizeof(var->constval));
2770                 ast_unref(cval);
2771             }
2772         }
2773
2774         if (parser->tok == ',') {
2775             /* another */
2776             continue;
2777         }
2778
2779         if (parser->tok != ';') {
2780             parseerror(parser, "missing semicolon");
2781             ast_value_delete(typevar);
2782             return false;
2783         }
2784
2785         (void)parser_next(parser);
2786
2787         ast_value_delete(typevar);
2788         return true;
2789     }
2790
2791 cleanup:
2792     ast_delete(typevar);
2793     if (var && cleanvar) ast_delete(var);
2794     if (varent.name) mem_d(varent.name);
2795     if (ve[0].name)  mem_d(ve[0].name);
2796     if (ve[1].name)  mem_d(ve[1].name);
2797     if (ve[2].name)  mem_d(ve[2].name);
2798     if (ve[0].var)   mem_d(ve[0].var);
2799     if (ve[1].var)   mem_d(ve[1].var);
2800     if (ve[2].var)   mem_d(ve[2].var);
2801
2802     return retval;
2803 }
2804
2805 static bool parser_global_statement(parser_t *parser)
2806 {
2807     if (parser->tok == TOKEN_TYPENAME || parser->tok == '.')
2808     {
2809         return parse_variable(parser, NULL);
2810     }
2811     else if (parser->tok == TOKEN_KEYWORD)
2812     {
2813         /* handle 'var' and 'const' */
2814         return false;
2815     }
2816     else if (parser->tok == '$')
2817     {
2818         if (!parser_next(parser)) {
2819             parseerror(parser, "parse error");
2820             return false;
2821         }
2822     }
2823     else
2824     {
2825         parseerror(parser, "unexpected token: %s", parser->lex->tok.value);
2826         return false;
2827     }
2828     return true;
2829 }
2830
2831 static parser_t *parser;
2832
2833 bool parser_init()
2834 {
2835     parser = (parser_t*)mem_a(sizeof(parser_t));
2836     if (!parser)
2837         return false;
2838
2839     memset(parser, 0, sizeof(*parser));
2840     return true;
2841 }
2842
2843 bool parser_compile()
2844 {
2845     /* initial lexer/parser state */
2846     parser->lex->flags.noops = true;
2847
2848     if (parser_next(parser))
2849     {
2850         while (parser->tok != TOKEN_EOF && parser->tok < TOKEN_ERROR)
2851         {
2852             if (!parser_global_statement(parser)) {
2853                 if (parser->tok == TOKEN_EOF)
2854                     parseerror(parser, "unexpected eof");
2855                 else if (!parser->errors)
2856                     parseerror(parser, "there have been errors, bailing out");
2857                 lex_close(parser->lex);
2858                 parser->lex = NULL;
2859                 return false;
2860             }
2861         }
2862     } else {
2863         parseerror(parser, "parse error");
2864         lex_close(parser->lex);
2865         parser->lex = NULL;
2866         return false;
2867     }
2868
2869     lex_close(parser->lex);
2870     parser->lex = NULL;
2871
2872     return !parser->errors;
2873 }
2874
2875 bool parser_compile_file(const char *filename)
2876 {
2877     parser->lex = lex_open(filename);
2878     if (!parser->lex) {
2879         printf("failed to open file \"%s\"\n", filename);
2880         return false;
2881     }
2882     return parser_compile();
2883 }
2884
2885 bool parser_compile_string(const char *name, const char *str)
2886 {
2887     parser->lex = lex_open_string(str, strlen(str), name);
2888     if (!parser->lex) {
2889         printf("failed to create lexer for string \"%s\"\n", name);
2890         return false;
2891     }
2892     return parser_compile();
2893 }
2894
2895 void parser_cleanup()
2896 {
2897     size_t i;
2898     for (i = 0; i < parser->functions_count; ++i) {
2899         ast_delete(parser->functions[i]);
2900     }
2901     for (i = 0; i < parser->imm_vector_count; ++i) {
2902         ast_delete(parser->imm_vector[i]);
2903     }
2904     for (i = 0; i < parser->imm_string_count; ++i) {
2905         ast_delete(parser->imm_string[i]);
2906     }
2907     for (i = 0; i < parser->imm_float_count; ++i) {
2908         ast_delete(parser->imm_float[i]);
2909     }
2910     for (i = 0; i < parser->fields_count; ++i) {
2911         ast_delete(parser->fields[i].var);
2912         mem_d(parser->fields[i].name);
2913     }
2914     for (i = 0; i < parser->globals_count; ++i) {
2915         ast_delete(parser->globals[i].var);
2916         mem_d(parser->globals[i].name);
2917     }
2918     MEM_VECTOR_CLEAR(parser, functions);
2919     MEM_VECTOR_CLEAR(parser, imm_vector);
2920     MEM_VECTOR_CLEAR(parser, imm_string);
2921     MEM_VECTOR_CLEAR(parser, imm_float);
2922     MEM_VECTOR_CLEAR(parser, globals);
2923     MEM_VECTOR_CLEAR(parser, fields);
2924     MEM_VECTOR_CLEAR(parser, locals);
2925
2926     mem_d(parser);
2927 }
2928
2929 static uint16_t progdefs_crc_sum(uint16_t old, const char *str)
2930 {
2931     return util_crc16(old, str, strlen(str));
2932 }
2933
2934 static void progdefs_crc_file(const char *str)
2935 {
2936     /* write to progdefs.h here */
2937 }
2938
2939 static uint16_t progdefs_crc_both(uint16_t old, const char *str)
2940 {
2941     old = progdefs_crc_sum(old, str);
2942     progdefs_crc_file(str);
2943     return old;
2944 }
2945
2946 static void generate_checksum(parser_t *parser)
2947 {
2948     uint16_t crc = 0xFFFF;
2949     size_t i;
2950
2951         crc = progdefs_crc_both(crc, "\n/* file generated by qcc, do not modify */\n\ntypedef struct\n{");
2952         crc = progdefs_crc_sum(crc, "\tint\tpad[28];\n");
2953         /*
2954         progdefs_crc_file("\tint\tpad;\n");
2955         progdefs_crc_file("\tint\tofs_return[3];\n");
2956         progdefs_crc_file("\tint\tofs_parm0[3];\n");
2957         progdefs_crc_file("\tint\tofs_parm1[3];\n");
2958         progdefs_crc_file("\tint\tofs_parm2[3];\n");
2959         progdefs_crc_file("\tint\tofs_parm3[3];\n");
2960         progdefs_crc_file("\tint\tofs_parm4[3];\n");
2961         progdefs_crc_file("\tint\tofs_parm5[3];\n");
2962         progdefs_crc_file("\tint\tofs_parm6[3];\n");
2963         progdefs_crc_file("\tint\tofs_parm7[3];\n");
2964         */
2965         for (i = 0; i < parser->crc_globals; ++i) {
2966             if (!ast_istype(parser->globals[i].var, ast_value))
2967                 continue;
2968             switch (parser->globals[i].var->expression.vtype) {
2969                 case TYPE_FLOAT:    crc = progdefs_crc_both(crc, "\tfloat\t"); break;
2970                 case TYPE_VECTOR:   crc = progdefs_crc_both(crc, "\tvec3_t\t"); break;
2971                 case TYPE_STRING:   crc = progdefs_crc_both(crc, "\tstring_t\t"); break;
2972                 case TYPE_FUNCTION: crc = progdefs_crc_both(crc, "\tfunc_t\t"); break;
2973                 default:
2974                     crc = progdefs_crc_both(crc, "\tint\t");
2975                     break;
2976             }
2977             crc = progdefs_crc_both(crc, parser->globals[i].name);
2978             crc = progdefs_crc_both(crc, ";\n");
2979         }
2980         crc = progdefs_crc_both(crc, "} globalvars_t;\n\ntypedef struct\n{\n");
2981         for (i = 0; i < parser->crc_fields; ++i) {
2982             if (!ast_istype(parser->fields[i].var, ast_value))
2983                 continue;
2984             switch (parser->fields[i].var->expression.next->expression.vtype) {
2985                 case TYPE_FLOAT:    crc = progdefs_crc_both(crc, "\tfloat\t"); break;
2986                 case TYPE_VECTOR:   crc = progdefs_crc_both(crc, "\tvec3_t\t"); break;
2987                 case TYPE_STRING:   crc = progdefs_crc_both(crc, "\tstring_t\t"); break;
2988                 case TYPE_FUNCTION: crc = progdefs_crc_both(crc, "\tfunc_t\t"); break;
2989                 default:
2990                     crc = progdefs_crc_both(crc, "\tint\t");
2991                     break;
2992             }
2993             crc = progdefs_crc_both(crc, parser->fields[i].name);
2994             crc = progdefs_crc_both(crc, ";\n");
2995         }
2996         crc = progdefs_crc_both(crc, "} entvars_t;\n\n");
2997
2998         code_crc = crc;
2999 }
3000
3001 bool parser_finish(const char *output)
3002 {
3003     size_t i;
3004     ir_builder *ir;
3005     bool retval = true;
3006
3007     if (!parser->errors)
3008     {
3009         ir = ir_builder_new("gmqcc_out");
3010         if (!ir) {
3011             printf("failed to allocate builder\n");
3012             return false;
3013         }
3014
3015         for (i = 0; i < parser->fields_count; ++i) {
3016             ast_value *field;
3017             bool isconst;
3018             if (!ast_istype(parser->fields[i].var, ast_value))
3019                 continue;
3020             field = (ast_value*)parser->fields[i].var;
3021             isconst = field->isconst;
3022             field->isconst = false;
3023             if (!ast_global_codegen((ast_value*)field, ir)) {
3024                 printf("failed to generate field %s\n", field->name);
3025                 ir_builder_delete(ir);
3026                 return false;
3027             }
3028             if (isconst) {
3029                 ir_value *ifld;
3030                 ast_expression *subtype;
3031                 field->isconst = true;
3032                 subtype = field->expression.next;
3033                 ifld = ir_builder_create_field(ir, field->name, subtype->expression.vtype);
3034                 if (subtype->expression.vtype == TYPE_FIELD)
3035                     ifld->fieldtype = subtype->expression.next->expression.vtype;
3036                 else if (subtype->expression.vtype == TYPE_FUNCTION)
3037                     ifld->outtype = subtype->expression.next->expression.vtype;
3038                 (void)!ir_value_set_field(field->ir_v, ifld);
3039             }
3040         }
3041         for (i = 0; i < parser->globals_count; ++i) {
3042             ast_value *asvalue;
3043             if (!ast_istype(parser->globals[i].var, ast_value))
3044                 continue;
3045             asvalue = (ast_value*)(parser->globals[i].var);
3046             if (!asvalue->uses && !asvalue->isconst && asvalue->expression.vtype != TYPE_FUNCTION) {
3047                 if (strcmp(asvalue->name, "end_sys_globals") &&
3048                     strcmp(asvalue->name, "end_sys_fields"))
3049                 {
3050                     retval = retval && !genwarning(ast_ctx(asvalue), WARN_UNUSED_VARIABLE,
3051                                                    "unused global: `%s`", asvalue->name);
3052                 }
3053             }
3054             if (!ast_global_codegen(asvalue, ir)) {
3055                 printf("failed to generate global %s\n", parser->globals[i].name);
3056                 ir_builder_delete(ir);
3057                 return false;
3058             }
3059         }
3060         for (i = 0; i < parser->imm_float_count; ++i) {
3061             if (!ast_global_codegen(parser->imm_float[i], ir)) {
3062                 printf("failed to generate global %s\n", parser->imm_float[i]->name);
3063                 ir_builder_delete(ir);
3064                 return false;
3065             }
3066         }
3067         for (i = 0; i < parser->imm_string_count; ++i) {
3068             if (!ast_global_codegen(parser->imm_string[i], ir)) {
3069                 printf("failed to generate global %s\n", parser->imm_string[i]->name);
3070                 ir_builder_delete(ir);
3071                 return false;
3072             }
3073         }
3074         for (i = 0; i < parser->imm_vector_count; ++i) {
3075             if (!ast_global_codegen(parser->imm_vector[i], ir)) {
3076                 printf("failed to generate global %s\n", parser->imm_vector[i]->name);
3077                 ir_builder_delete(ir);
3078                 return false;
3079             }
3080         }
3081         for (i = 0; i < parser->functions_count; ++i) {
3082             if (!ast_function_codegen(parser->functions[i], ir)) {
3083                 printf("failed to generate function %s\n", parser->functions[i]->name);
3084                 ir_builder_delete(ir);
3085                 return false;
3086             }
3087             if (!ir_function_finalize(parser->functions[i]->ir_func)) {
3088                 printf("failed to finalize function %s\n", parser->functions[i]->name);
3089                 ir_builder_delete(ir);
3090                 return false;
3091             }
3092         }
3093
3094         if (retval) {
3095             if (opts_dump)
3096                 ir_builder_dump(ir, printf);
3097
3098             generate_checksum(parser);
3099
3100             if (!ir_builder_generate(ir, output)) {
3101                 printf("*** failed to generate output file\n");
3102                 ir_builder_delete(ir);
3103                 return false;
3104             }
3105         }
3106
3107         ir_builder_delete(ir);
3108         return retval;
3109     }
3110
3111     printf("*** there were compile errors\n");
3112     return false;
3113 }