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