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