]> git.xonotic.org Git - xonotic/gmqcc.git/blob - parser.c
41a87302a1721382a592ec084832cc9c3842099c
[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     varentry_t    *globals;
17     varentry_t    *fields;
18     ast_function **functions;
19     ast_value    **imm_float;
20     ast_value    **imm_string;
21     ast_value    **imm_vector;
22
23     /* must be deleted first, they reference immediates and values */
24     ast_value    **accessors;
25
26     ast_value *imm_float_zero;
27     ast_value *imm_float_one;
28     ast_value *imm_vector_zero;
29
30     size_t crc_globals;
31     size_t crc_fields;
32
33     ast_function *function;
34     varentry_t *locals;
35     size_t blocklocal;
36
37     size_t errors;
38
39     /* we store the '=' operator info */
40     const oper_info *assign_op;
41
42     /* TYPE_FIELD -> parser_find_fields is used instead of find_var
43      * TODO: TYPE_VECTOR -> x, y and z are accepted in the gmqcc standard
44      * anything else: type error
45      */
46     qcint  memberof;
47 } parser_t;
48
49
50 static bool GMQCC_WARN parser_pop_local(parser_t *parser);
51 static bool parse_variable(parser_t *parser, ast_block *localblock, bool nofields, bool is_const);
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 bool parse_statement(parser_t *parser, ast_block *block, ast_expression **out, bool allow_cases);
56 static ast_expression* parse_expression_leave(parser_t *parser, bool stopatcomma);
57 static ast_expression* parse_expression(parser_t *parser, bool stopatcomma);
58
59 static void parseerror(parser_t *parser, const char *fmt, ...)
60 {
61         va_list ap;
62
63         parser->errors++;
64
65         va_start(ap, fmt);
66     con_vprintmsg(LVL_ERROR, parser->lex->tok.ctx.file, parser->lex->tok.ctx.line, "parse error", fmt, ap);
67         va_end(ap);
68 }
69
70 /* returns true if it counts as an error */
71 static bool GMQCC_WARN parsewarning(parser_t *parser, int warntype, const char *fmt, ...)
72 {
73         va_list ap;
74         int lvl = LVL_WARNING;
75
76     if (!OPTS_WARN(warntype))
77         return false;
78
79     if (opts_werror) {
80             parser->errors++;
81             lvl = LVL_ERROR;
82         }
83
84         va_start(ap, fmt);
85     con_vprintmsg(lvl, parser->lex->tok.ctx.file, parser->lex->tok.ctx.line, "warning", fmt, ap);
86         va_end(ap);
87
88         return opts_werror;
89 }
90
91 static bool GMQCC_WARN genwarning(lex_ctx ctx, int warntype, const char *fmt, ...)
92 {
93         va_list ap;
94         int lvl = LVL_WARNING;
95
96     if (!OPTS_WARN(warntype))
97         return false;
98
99     if (opts_werror)
100             lvl = LVL_ERROR;
101
102         va_start(ap, fmt);
103     con_vprintmsg(lvl, ctx.file, ctx.line, "warning", fmt, ap);
104         va_end(ap);
105
106         return opts_werror;
107 }
108
109 /**********************************************************************
110  * some maths used for constant folding
111  */
112
113 vector vec3_add(vector a, vector b)
114 {
115     vector out;
116     out.x = a.x + b.x;
117     out.y = a.y + b.y;
118     out.z = a.z + b.z;
119     return out;
120 }
121
122 vector vec3_sub(vector a, vector b)
123 {
124     vector out;
125     out.x = a.x - b.x;
126     out.y = a.y - b.y;
127     out.z = a.z - b.z;
128     return out;
129 }
130
131 qcfloat vec3_mulvv(vector a, vector b)
132 {
133     return (a.x * b.x + a.y * b.y + a.z * b.z);
134 }
135
136 vector vec3_mulvf(vector a, float b)
137 {
138     vector out;
139     out.x = a.x * b;
140     out.y = a.y * b;
141     out.z = a.z * b;
142     return out;
143 }
144
145 /**********************************************************************
146  * parsing
147  */
148
149 bool parser_next(parser_t *parser)
150 {
151     /* lex_do kills the previous token */
152     parser->tok = lex_do(parser->lex);
153     if (parser->tok == TOKEN_EOF)
154         return true;
155     if (parser->tok >= TOKEN_ERROR) {
156         parseerror(parser, "lex error");
157         return false;
158     }
159     return true;
160 }
161
162 #define parser_tokval(p) ((p)->lex->tok.value)
163 #define parser_token(p)  (&((p)->lex->tok))
164 #define parser_ctx(p)    ((p)->lex->tok.ctx)
165
166 static ast_value* parser_const_float(parser_t *parser, double d)
167 {
168     size_t i;
169     ast_value *out;
170     for (i = 0; i < vec_size(parser->imm_float); ++i) {
171         const double compare = parser->imm_float[i]->constval.vfloat;
172         if (memcmp((const void*)&compare, (const void *)&d, sizeof(double)) == 0)
173             return parser->imm_float[i];
174     }
175     out = ast_value_new(parser_ctx(parser), "#IMMEDIATE", TYPE_FLOAT);
176     out->isconst = true;
177     out->constval.vfloat = d;
178     vec_push(parser->imm_float, out);
179     return out;
180 }
181
182 static ast_value* parser_const_float_0(parser_t *parser)
183 {
184     if (!parser->imm_float_zero)
185         parser->imm_float_zero = parser_const_float(parser, 0);
186     return parser->imm_float_zero;
187 }
188
189 static ast_value* parser_const_float_1(parser_t *parser)
190 {
191     if (!parser->imm_float_one)
192         parser->imm_float_one = parser_const_float(parser, 1);
193     return parser->imm_float_one;
194 }
195
196 static char *parser_strdup(const char *str)
197 {
198     if (str && !*str) {
199         /* actually dup empty strings */
200         char *out = mem_a(1);
201         *out = 0;
202         return out;
203     }
204     return util_strdup(str);
205 }
206
207 static ast_value* parser_const_string(parser_t *parser, const char *str)
208 {
209     size_t i;
210     ast_value *out;
211     for (i = 0; i < vec_size(parser->imm_string); ++i) {
212         if (!strcmp(parser->imm_string[i]->constval.vstring, str))
213             return parser->imm_string[i];
214     }
215     out = ast_value_new(parser_ctx(parser), "#IMMEDIATE", TYPE_STRING);
216     out->isconst = true;
217     out->constval.vstring = parser_strdup(str);
218     vec_push(parser->imm_string, out);
219     return out;
220 }
221
222 static ast_value* parser_const_vector(parser_t *parser, vector v)
223 {
224     size_t i;
225     ast_value *out;
226     for (i = 0; i < vec_size(parser->imm_vector); ++i) {
227         if (!memcmp(&parser->imm_vector[i]->constval.vvec, &v, sizeof(v)))
228             return parser->imm_vector[i];
229     }
230     out = ast_value_new(parser_ctx(parser), "#IMMEDIATE", TYPE_VECTOR);
231     out->isconst = true;
232     out->constval.vvec = v;
233     vec_push(parser->imm_vector, out);
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 < vec_size(parser->fields); ++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 < vec_size(parser->globals); ++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 < vec_size(fun->expression.params); ++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 = vec_size(parser->locals); 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     sy_elem *out;
321     sy_elem *ops;
322 } shunt;
323
324 #define SY_PAREN_EXPR '('
325 #define SY_PAREN_FUNC 'f'
326 #define SY_PAREN_INDEX '['
327
328 static sy_elem syexp(lex_ctx ctx, ast_expression *v) {
329     sy_elem e;
330     e.etype = 0;
331     e.off   = 0;
332     e.out   = v;
333     e.block = NULL;
334     e.ctx   = ctx;
335     e.paren = 0;
336     return e;
337 }
338
339 static sy_elem syblock(lex_ctx ctx, ast_block *v) {
340     sy_elem e;
341     e.etype = 0;
342     e.off   = 0;
343     e.out   = (ast_expression*)v;
344     e.block = v;
345     e.ctx   = ctx;
346     e.paren = 0;
347     return e;
348 }
349
350 static sy_elem syop(lex_ctx ctx, const oper_info *op) {
351     sy_elem e;
352     e.etype = 1 + (op - operators);
353     e.off   = 0;
354     e.out   = NULL;
355     e.block = NULL;
356     e.ctx   = ctx;
357     e.paren = 0;
358     return e;
359 }
360
361 static sy_elem syparen(lex_ctx ctx, int p, size_t off) {
362     sy_elem e;
363     e.etype = 0;
364     e.off   = off;
365     e.out   = NULL;
366     e.block = NULL;
367     e.ctx   = ctx;
368     e.paren = p;
369     return e;
370 }
371
372 #ifdef DEBUGSHUNT
373 # define DEBUGSHUNTDO(x) x
374 #else
375 # define DEBUGSHUNTDO(x)
376 #endif
377
378 /* With regular precedence rules, ent.foo[n] is the same as (ent.foo)[n],
379  * so we need to rotate it to become ent.(foo[n]).
380  */
381 static bool rotate_entfield_array_index_nodes(ast_expression **out)
382 {
383     ast_array_index *index;
384     ast_entfield    *entfield;
385
386     ast_value       *field;
387     ast_expression  *sub;
388     ast_expression  *entity;
389
390     lex_ctx ctx = ast_ctx(*out);
391
392     if (!ast_istype(*out, ast_array_index))
393         return false;
394     index = (ast_array_index*)*out;
395
396     if (!ast_istype(index->array, ast_entfield))
397         return false;
398     entfield = (ast_entfield*)index->array;
399
400     if (!ast_istype(entfield->field, ast_value))
401         return false;
402     field = (ast_value*)entfield->field;
403
404     sub    = index->index;
405     entity = entfield->entity;
406
407     ast_delete(index);
408
409     index = ast_array_index_new(ctx, (ast_expression*)field, sub);
410     entfield = ast_entfield_new(ctx, entity, (ast_expression*)index);
411     *out = (ast_expression*)entfield;
412
413     return true;
414 }
415
416 static bool parser_sy_pop(parser_t *parser, shunt *sy)
417 {
418     const oper_info *op;
419     lex_ctx ctx;
420     ast_expression *out = NULL;
421     ast_expression *exprs[3];
422     ast_block      *blocks[3];
423     ast_value      *asvalue[3];
424     size_t i, assignop, addop, subop;
425     qcint  generated_op = 0;
426
427     char ty1[1024];
428     char ty2[1024];
429
430     if (!vec_size(sy->ops)) {
431         parseerror(parser, "internal error: missing operator");
432         return false;
433     }
434
435     if (vec_last(sy->ops).paren) {
436         parseerror(parser, "unmatched parenthesis");
437         return false;
438     }
439
440     op = &operators[vec_last(sy->ops).etype - 1];
441     ctx = vec_last(sy->ops).ctx;
442
443     DEBUGSHUNTDO(con_out("apply %s\n", op->op));
444
445     if (vec_size(sy->out) < op->operands) {
446         parseerror(parser, "internal error: not enough operands: %i (operator %s (%i))", vec_size(sy->out),
447                    op->op, (int)op->id);
448         return false;
449     }
450
451     vec_shrinkby(sy->ops, 1);
452
453     vec_shrinkby(sy->out, op->operands);
454     for (i = 0; i < op->operands; ++i) {
455         exprs[i]  = sy->out[vec_size(sy->out)+i].out;
456         blocks[i] = sy->out[vec_size(sy->out)+i].block;
457         asvalue[i] = (ast_value*)exprs[i];
458     }
459
460     if (blocks[0] && !vec_size(blocks[0]->exprs) && op->id != opid1(',')) {
461         parseerror(parser, "internal error: operator cannot be applied on empty blocks");
462         return false;
463     }
464
465 #define NotSameType(T) \
466              (exprs[0]->expression.vtype != exprs[1]->expression.vtype || \
467               exprs[0]->expression.vtype != T)
468 #define CanConstFold1(A) \
469              (ast_istype((A), ast_value) && ((ast_value*)(A))->isconst)
470 #define CanConstFold(A, B) \
471              (CanConstFold1(A) && CanConstFold1(B))
472 #define ConstV(i) (asvalue[(i)]->constval.vvec)
473 #define ConstF(i) (asvalue[(i)]->constval.vfloat)
474 #define ConstS(i) (asvalue[(i)]->constval.vstring)
475     switch (op->id)
476     {
477         default:
478             parseerror(parser, "internal error: unhandled operator: %s (%i)", op->op, (int)op->id);
479             return false;
480
481         case opid1('.'):
482             if (exprs[0]->expression.vtype == TYPE_ENTITY) {
483                 if (exprs[1]->expression.vtype != TYPE_FIELD) {
484                     parseerror(parser, "type error: right hand of member-operand should be an entity-field");
485                     return false;
486                 }
487                 out = (ast_expression*)ast_entfield_new(ctx, exprs[0], exprs[1]);
488             }
489             else if (exprs[0]->expression.vtype == TYPE_VECTOR) {
490                 parseerror(parser, "internal error: vector access is not supposed to be handled at this point");
491                 return false;
492             }
493             else {
494                 parseerror(parser, "type error: member-of operator on something that is not an entity or vector");
495                 return false;
496             }
497             break;
498
499         case opid1('['):
500             if (exprs[0]->expression.vtype != TYPE_ARRAY &&
501                 !(exprs[0]->expression.vtype == TYPE_FIELD &&
502                   exprs[0]->expression.next->expression.vtype == TYPE_ARRAY))
503             {
504                 ast_type_to_string(exprs[0], ty1, sizeof(ty1));
505                 parseerror(parser, "cannot index value of type %s", ty1);
506                 return false;
507             }
508             if (exprs[1]->expression.vtype != TYPE_FLOAT) {
509                 ast_type_to_string(exprs[0], ty1, sizeof(ty1));
510                 parseerror(parser, "index must be of type float, not %s", ty1);
511                 return false;
512             }
513             out = (ast_expression*)ast_array_index_new(ctx, exprs[0], exprs[1]);
514             if (rotate_entfield_array_index_nodes(&out))
515             {
516                 if (opts_standard != COMPILER_GMQCC) {
517                     /* this error doesn't need to make us bail out */
518                     (void)!parsewarning(parser, WARN_EXTENSIONS,
519                                         "accessing array-field members of an entity without parenthesis\n"
520                                         " -> this is an extension from -std=gmqcc");
521                 }
522             }
523             break;
524
525         case opid1(','):
526             if (blocks[0]) {
527                 vec_push(blocks[0]->exprs, exprs[1]);
528             } else {
529                 blocks[0] = ast_block_new(ctx);
530                 vec_push(blocks[0]->exprs, exprs[0]);
531                 vec_push(blocks[0]->exprs, exprs[1]);
532             }
533             if (!ast_block_set_type(blocks[0], exprs[1]))
534                 return false;
535
536             vec_push(sy->out, syblock(ctx, blocks[0]));
537             return true;
538
539         case opid2('-','P'):
540             switch (exprs[0]->expression.vtype) {
541                 case TYPE_FLOAT:
542                     if (CanConstFold1(exprs[0]))
543                         out = (ast_expression*)parser_const_float(parser, -ConstF(0));
544                     else
545                         out = (ast_expression*)ast_binary_new(ctx, INSTR_SUB_F,
546                                                               (ast_expression*)parser_const_float_0(parser),
547                                                               exprs[0]);
548                     break;
549                 case TYPE_VECTOR:
550                     if (CanConstFold1(exprs[0]))
551                         out = (ast_expression*)parser_const_vector_f(parser,
552                             -ConstV(0).x, -ConstV(0).y, -ConstV(0).z);
553                     else
554                         out = (ast_expression*)ast_binary_new(ctx, INSTR_SUB_V,
555                                                               (ast_expression*)parser_const_vector_0(parser),
556                                                               exprs[0]);
557                     break;
558                 default:
559                 parseerror(parser, "invalid types used in expression: cannot negate type %s",
560                            type_name[exprs[0]->expression.vtype]);
561                 return false;
562             }
563             break;
564
565         case opid2('!','P'):
566             switch (exprs[0]->expression.vtype) {
567                 case TYPE_FLOAT:
568                     if (CanConstFold1(exprs[0]))
569                         out = (ast_expression*)parser_const_float(parser, !ConstF(0));
570                     else
571                         out = (ast_expression*)ast_unary_new(ctx, INSTR_NOT_F, exprs[0]);
572                     break;
573                 case TYPE_VECTOR:
574                     if (CanConstFold1(exprs[0]))
575                         out = (ast_expression*)parser_const_float(parser,
576                             (!ConstV(0).x && !ConstV(0).y && !ConstV(0).z));
577                     else
578                         out = (ast_expression*)ast_unary_new(ctx, INSTR_NOT_V, exprs[0]);
579                     break;
580                 case TYPE_STRING:
581                     if (CanConstFold1(exprs[0]))
582                         out = (ast_expression*)parser_const_float(parser, !ConstS(0) || !*ConstS(0));
583                     else
584                         out = (ast_expression*)ast_unary_new(ctx, INSTR_NOT_S, exprs[0]);
585                     break;
586                 /* we don't constant-fold NOT for these types */
587                 case TYPE_ENTITY:
588                     out = (ast_expression*)ast_unary_new(ctx, INSTR_NOT_ENT, exprs[0]);
589                     break;
590                 case TYPE_FUNCTION:
591                     out = (ast_expression*)ast_unary_new(ctx, INSTR_NOT_FNC, exprs[0]);
592                     break;
593                 default:
594                 parseerror(parser, "invalid types used in expression: cannot logically negate type %s",
595                            type_name[exprs[0]->expression.vtype]);
596                 return false;
597             }
598             break;
599
600         case opid1('+'):
601             if (exprs[0]->expression.vtype != exprs[1]->expression.vtype ||
602                 (exprs[0]->expression.vtype != TYPE_VECTOR && exprs[0]->expression.vtype != TYPE_FLOAT) )
603             {
604                 parseerror(parser, "invalid types used in expression: cannot add type %s and %s",
605                            type_name[exprs[0]->expression.vtype],
606                            type_name[exprs[1]->expression.vtype]);
607                 return false;
608             }
609             switch (exprs[0]->expression.vtype) {
610                 case TYPE_FLOAT:
611                     if (CanConstFold(exprs[0], exprs[1]))
612                     {
613                         out = (ast_expression*)parser_const_float(parser, ConstF(0) + ConstF(1));
614                     }
615                     else
616                         out = (ast_expression*)ast_binary_new(ctx, INSTR_ADD_F, exprs[0], exprs[1]);
617                     break;
618                 case TYPE_VECTOR:
619                     if (CanConstFold(exprs[0], exprs[1]))
620                         out = (ast_expression*)parser_const_vector(parser, vec3_add(ConstV(0), ConstV(1)));
621                     else
622                         out = (ast_expression*)ast_binary_new(ctx, INSTR_ADD_V, exprs[0], exprs[1]);
623                     break;
624                 default:
625                     parseerror(parser, "invalid types used in expression: cannot add type %s and %s",
626                                type_name[exprs[0]->expression.vtype],
627                                type_name[exprs[1]->expression.vtype]);
628                     return false;
629             };
630             break;
631         case opid1('-'):
632             if (exprs[0]->expression.vtype != exprs[1]->expression.vtype ||
633                 (exprs[0]->expression.vtype != TYPE_VECTOR && exprs[0]->expression.vtype != TYPE_FLOAT) )
634             {
635                 parseerror(parser, "invalid types used in expression: cannot subtract type %s from %s",
636                            type_name[exprs[1]->expression.vtype],
637                            type_name[exprs[0]->expression.vtype]);
638                 return false;
639             }
640             switch (exprs[0]->expression.vtype) {
641                 case TYPE_FLOAT:
642                     if (CanConstFold(exprs[0], exprs[1]))
643                         out = (ast_expression*)parser_const_float(parser, ConstF(0) - ConstF(1));
644                     else
645                         out = (ast_expression*)ast_binary_new(ctx, INSTR_SUB_F, exprs[0], exprs[1]);
646                     break;
647                 case TYPE_VECTOR:
648                     if (CanConstFold(exprs[0], exprs[1]))
649                         out = (ast_expression*)parser_const_vector(parser, vec3_sub(ConstV(0), ConstV(1)));
650                     else
651                         out = (ast_expression*)ast_binary_new(ctx, INSTR_SUB_V, exprs[0], exprs[1]);
652                     break;
653                 default:
654                     parseerror(parser, "invalid types used in expression: cannot subtract type %s from %s",
655                                type_name[exprs[1]->expression.vtype],
656                                type_name[exprs[0]->expression.vtype]);
657                     return false;
658             };
659             break;
660         case opid1('*'):
661             if (exprs[0]->expression.vtype != exprs[1]->expression.vtype &&
662                 exprs[0]->expression.vtype != TYPE_VECTOR &&
663                 exprs[0]->expression.vtype != TYPE_FLOAT &&
664                 exprs[1]->expression.vtype != TYPE_VECTOR &&
665                 exprs[1]->expression.vtype != TYPE_FLOAT)
666             {
667                 parseerror(parser, "invalid types used in expression: cannot multiply types %s and %s",
668                            type_name[exprs[1]->expression.vtype],
669                            type_name[exprs[0]->expression.vtype]);
670                 return false;
671             }
672             switch (exprs[0]->expression.vtype) {
673                 case TYPE_FLOAT:
674                     if (exprs[1]->expression.vtype == TYPE_VECTOR)
675                     {
676                         if (CanConstFold(exprs[0], exprs[1]))
677                             out = (ast_expression*)parser_const_vector(parser, vec3_mulvf(ConstV(1), ConstF(0)));
678                         else
679                             out = (ast_expression*)ast_binary_new(ctx, INSTR_MUL_FV, exprs[0], exprs[1]);
680                     }
681                     else
682                     {
683                         if (CanConstFold(exprs[0], exprs[1]))
684                             out = (ast_expression*)parser_const_float(parser, ConstF(0) * ConstF(1));
685                         else
686                             out = (ast_expression*)ast_binary_new(ctx, INSTR_MUL_F, exprs[0], exprs[1]);
687                     }
688                     break;
689                 case TYPE_VECTOR:
690                     if (exprs[1]->expression.vtype == TYPE_FLOAT)
691                     {
692                         if (CanConstFold(exprs[0], exprs[1]))
693                             out = (ast_expression*)parser_const_vector(parser, vec3_mulvf(ConstV(0), ConstF(1)));
694                         else
695                             out = (ast_expression*)ast_binary_new(ctx, INSTR_MUL_VF, exprs[0], exprs[1]);
696                     }
697                     else
698                     {
699                         if (CanConstFold(exprs[0], exprs[1]))
700                             out = (ast_expression*)parser_const_float(parser, vec3_mulvv(ConstV(0), ConstV(1)));
701                         else
702                             out = (ast_expression*)ast_binary_new(ctx, INSTR_MUL_V, exprs[0], exprs[1]);
703                     }
704                     break;
705                 default:
706                     parseerror(parser, "invalid types used in expression: cannot multiply types %s and %s",
707                                type_name[exprs[1]->expression.vtype],
708                                type_name[exprs[0]->expression.vtype]);
709                     return false;
710             };
711             break;
712         case opid1('/'):
713             if (NotSameType(TYPE_FLOAT)) {
714                 parseerror(parser, "invalid types used in expression: cannot divide types %s and %s",
715                            type_name[exprs[0]->expression.vtype],
716                            type_name[exprs[1]->expression.vtype]);
717                 return false;
718             }
719             if (CanConstFold(exprs[0], exprs[1]))
720                 out = (ast_expression*)parser_const_float(parser, ConstF(0) / ConstF(1));
721             else
722                 out = (ast_expression*)ast_binary_new(ctx, INSTR_DIV_F, exprs[0], exprs[1]);
723             break;
724         case opid1('%'):
725         case opid2('%','='):
726             parseerror(parser, "qc does not have a modulo operator");
727             return false;
728         case opid1('|'):
729         case opid1('&'):
730             if (NotSameType(TYPE_FLOAT)) {
731                 parseerror(parser, "invalid types used in expression: cannot perform bit operations between types %s and %s",
732                            type_name[exprs[0]->expression.vtype],
733                            type_name[exprs[1]->expression.vtype]);
734                 return false;
735             }
736             if (CanConstFold(exprs[0], exprs[1]))
737                 out = (ast_expression*)parser_const_float(parser,
738                     (op->id == opid1('|') ? (float)( ((qcint)ConstF(0)) | ((qcint)ConstF(1)) ) :
739                                             (float)( ((qcint)ConstF(0)) & ((qcint)ConstF(1)) ) ));
740             else
741                 out = (ast_expression*)ast_binary_new(ctx,
742                     (op->id == opid1('|') ? INSTR_BITOR : INSTR_BITAND),
743                     exprs[0], exprs[1]);
744             break;
745         case opid1('^'):
746             parseerror(parser, "TODO: bitxor");
747             return false;
748
749         case opid2('<','<'):
750         case opid2('>','>'):
751         case opid3('<','<','='):
752         case opid3('>','>','='):
753             parseerror(parser, "TODO: shifts");
754             return false;
755
756         case opid2('|','|'):
757             generated_op += 1; /* INSTR_OR */
758         case opid2('&','&'):
759             generated_op += INSTR_AND;
760             if (NotSameType(TYPE_FLOAT)) {
761                 parseerror(parser, "invalid types used in expression: cannot perform logical operations between types %s and %s",
762                            type_name[exprs[0]->expression.vtype],
763                            type_name[exprs[1]->expression.vtype]);
764                 parseerror(parser, "TODO: logical ops for arbitrary types using INSTR_NOT");
765                 parseerror(parser, "TODO: optional early out");
766                 return false;
767             }
768             if (opts_standard == COMPILER_GMQCC)
769                 con_out("TODO: early out logic\n");
770             if (CanConstFold(exprs[0], exprs[1]))
771                 out = (ast_expression*)parser_const_float(parser,
772                     (generated_op == INSTR_OR ? (ConstF(0) || ConstF(1)) : (ConstF(0) && ConstF(1))));
773             else
774                 out = (ast_expression*)ast_binary_new(ctx, generated_op, exprs[0], exprs[1]);
775             break;
776
777         case opid2('?',':'):
778             if (exprs[1]->expression.vtype != exprs[2]->expression.vtype) {
779                 ast_type_to_string(exprs[1], ty1, sizeof(ty1));
780                 ast_type_to_string(exprs[2], ty2, sizeof(ty2));
781                 parseerror(parser, "iperands of ternary expression must have the same type, got %s and %s", ty1, ty2);
782                 return false;
783             }
784             if (CanConstFold1(exprs[0]))
785                 out = (ConstF(0) ? exprs[1] : exprs[2]);
786             else
787                 out = (ast_expression*)ast_ternary_new(ctx, exprs[0], exprs[1], exprs[2]);
788             break;
789
790         case opid1('>'):
791             generated_op += 1; /* INSTR_GT */
792         case opid1('<'):
793             generated_op += 1; /* INSTR_LT */
794         case opid2('>', '='):
795             generated_op += 1; /* INSTR_GE */
796         case opid2('<', '='):
797             generated_op += INSTR_LE;
798             if (NotSameType(TYPE_FLOAT)) {
799                 parseerror(parser, "invalid types used in expression: cannot perform comparison between types %s and %s",
800                            type_name[exprs[0]->expression.vtype],
801                            type_name[exprs[1]->expression.vtype]);
802                 return false;
803             }
804             out = (ast_expression*)ast_binary_new(ctx, generated_op, exprs[0], exprs[1]);
805             break;
806         case opid2('!', '='):
807             if (exprs[0]->expression.vtype != exprs[1]->expression.vtype) {
808                 parseerror(parser, "invalid types used in expression: cannot perform comparison between types %s and %s",
809                            type_name[exprs[0]->expression.vtype],
810                            type_name[exprs[1]->expression.vtype]);
811                 return false;
812             }
813             out = (ast_expression*)ast_binary_new(ctx, type_ne_instr[exprs[0]->expression.vtype], exprs[0], exprs[1]);
814             break;
815         case opid2('=', '='):
816             if (exprs[0]->expression.vtype != exprs[1]->expression.vtype) {
817                 parseerror(parser, "invalid types used in expression: cannot perform comparison between types %s and %s",
818                            type_name[exprs[0]->expression.vtype],
819                            type_name[exprs[1]->expression.vtype]);
820                 return false;
821             }
822             out = (ast_expression*)ast_binary_new(ctx, type_eq_instr[exprs[0]->expression.vtype], exprs[0], exprs[1]);
823             break;
824
825         case opid1('='):
826             if (ast_istype(exprs[0], ast_entfield)) {
827                 ast_expression *field = ((ast_entfield*)exprs[0])->field;
828                 if (OPTS_FLAG(ADJUST_VECTOR_FIELDS) &&
829                     exprs[0]->expression.vtype == TYPE_FIELD &&
830                     exprs[0]->expression.next->expression.vtype == TYPE_VECTOR)
831                 {
832                     assignop = type_storep_instr[TYPE_VECTOR];
833                 }
834                 else
835                     assignop = type_storep_instr[exprs[0]->expression.vtype];
836                 if (!ast_compare_type(field->expression.next, exprs[1])) {
837                     ast_type_to_string(field->expression.next, ty1, sizeof(ty1));
838                     ast_type_to_string(exprs[1], ty2, sizeof(ty2));
839                     if (opts_standard == COMPILER_QCC &&
840                         field->expression.next->expression.vtype == TYPE_FUNCTION &&
841                         exprs[1]->expression.vtype == TYPE_FUNCTION)
842                     {
843                         if (parsewarning(parser, WARN_ASSIGN_FUNCTION_TYPES,
844                                          "invalid types in assignment: cannot assign %s to %s", ty2, ty1))
845                         {
846                             parser->errors++;
847                         }
848                     }
849                     else
850                         parseerror(parser, "invalid types in assignment: cannot assign %s to %s", ty2, ty1);
851                 }
852             }
853             else
854             {
855                 if (OPTS_FLAG(ADJUST_VECTOR_FIELDS) &&
856                     exprs[0]->expression.vtype == TYPE_FIELD &&
857                     exprs[0]->expression.next->expression.vtype == TYPE_VECTOR)
858                 {
859                     assignop = type_store_instr[TYPE_VECTOR];
860                 }
861                 else {
862                     assignop = type_store_instr[exprs[0]->expression.vtype];
863                 }
864
865                 if (assignop == AINSTR_END) {
866                     ast_type_to_string(exprs[0], ty1, sizeof(ty1));
867                     ast_type_to_string(exprs[1], ty2, sizeof(ty2));
868                     parseerror(parser, "invalid types in assignment: cannot assign %s to %s", ty2, ty1);
869                 }
870                 else if (!ast_compare_type(exprs[0], exprs[1])) {
871                     ast_type_to_string(exprs[0], ty1, sizeof(ty1));
872                     ast_type_to_string(exprs[1], ty2, sizeof(ty2));
873                     if (opts_standard == COMPILER_QCC &&
874                         exprs[0]->expression.vtype == TYPE_FUNCTION &&
875                         exprs[1]->expression.vtype == TYPE_FUNCTION)
876                     {
877                         if (parsewarning(parser, WARN_ASSIGN_FUNCTION_TYPES,
878                                          "invalid types in assignment: cannot assign %s to %s", ty2, ty1))
879                         {
880                             parser->errors++;
881                         }
882                     }
883                     else
884                         parseerror(parser, "invalid types in assignment: cannot assign %s to %s", ty2, ty1);
885                 }
886             }
887             out = (ast_expression*)ast_store_new(ctx, assignop, exprs[0], exprs[1]);
888             break;
889         case opid3('+','+','P'):
890         case opid3('-','-','P'):
891             /* prefix ++ */
892             if (exprs[0]->expression.vtype != TYPE_FLOAT) {
893                 ast_type_to_string(exprs[0], ty1, sizeof(ty1));
894                 parseerror(parser, "invalid type for prefix increment: %s", ty1);
895                 return false;
896             }
897             if (op->id == opid3('+','+','P'))
898                 addop = INSTR_ADD_F;
899             else
900                 addop = INSTR_SUB_F;
901             if (ast_istype(exprs[0], ast_entfield)) {
902                 out = (ast_expression*)ast_binstore_new(ctx, INSTR_STOREP_F, addop,
903                                                         exprs[0],
904                                                         (ast_expression*)parser_const_float_1(parser));
905             } else {
906                 out = (ast_expression*)ast_binstore_new(ctx, INSTR_STORE_F, addop,
907                                                         exprs[0],
908                                                         (ast_expression*)parser_const_float_1(parser));
909             }
910             break;
911         case opid3('S','+','+'):
912         case opid3('S','-','-'):
913             /* prefix ++ */
914             if (exprs[0]->expression.vtype != TYPE_FLOAT) {
915                 ast_type_to_string(exprs[0], ty1, sizeof(ty1));
916                 parseerror(parser, "invalid type for suffix increment: %s", ty1);
917                 return false;
918             }
919             if (op->id == opid3('S','+','+')) {
920                 addop = INSTR_ADD_F;
921                 subop = INSTR_SUB_F;
922             } else {
923                 addop = INSTR_SUB_F;
924                 subop = INSTR_ADD_F;
925             }
926             if (ast_istype(exprs[0], ast_entfield)) {
927                 out = (ast_expression*)ast_binstore_new(ctx, INSTR_STOREP_F, addop,
928                                                         exprs[0],
929                                                         (ast_expression*)parser_const_float_1(parser));
930             } else {
931                 out = (ast_expression*)ast_binstore_new(ctx, INSTR_STORE_F, addop,
932                                                         exprs[0],
933                                                         (ast_expression*)parser_const_float_1(parser));
934             }
935             if (!out)
936                 return false;
937             out = (ast_expression*)ast_binary_new(ctx, subop,
938                                                   out,
939                                                   (ast_expression*)parser_const_float_1(parser));
940             break;
941         case opid2('+','='):
942         case opid2('-','='):
943             if (exprs[0]->expression.vtype != exprs[1]->expression.vtype ||
944                 (exprs[0]->expression.vtype != TYPE_VECTOR && exprs[0]->expression.vtype != TYPE_FLOAT) )
945             {
946                 ast_type_to_string(exprs[0], ty1, sizeof(ty1));
947                 ast_type_to_string(exprs[1], ty2, sizeof(ty2));
948                 parseerror(parser, "invalid types used in expression: cannot add or subtract type %s and %s",
949                            ty1, ty2);
950                 return false;
951             }
952             if (ast_istype(exprs[0], ast_entfield))
953                 assignop = type_storep_instr[exprs[0]->expression.vtype];
954             else
955                 assignop = type_store_instr[exprs[0]->expression.vtype];
956             switch (exprs[0]->expression.vtype) {
957                 case TYPE_FLOAT:
958                     out = (ast_expression*)ast_binstore_new(ctx, assignop,
959                                                             (op->id == opid2('+','=') ? INSTR_ADD_F : INSTR_SUB_F),
960                                                             exprs[0], exprs[1]);
961                     break;
962                 case TYPE_VECTOR:
963                     out = (ast_expression*)ast_binstore_new(ctx, assignop,
964                                                             (op->id == opid2('+','=') ? INSTR_ADD_V : INSTR_SUB_V),
965                                                             exprs[0], exprs[1]);
966                     break;
967                 default:
968                     parseerror(parser, "invalid types used in expression: cannot add or subtract type %s and %s",
969                                type_name[exprs[0]->expression.vtype],
970                                type_name[exprs[1]->expression.vtype]);
971                     return false;
972             };
973             break;
974         case opid2('*','='):
975         case opid2('/','='):
976             if (exprs[1]->expression.vtype != TYPE_FLOAT ||
977                 !(exprs[0]->expression.vtype == TYPE_FLOAT ||
978                   exprs[0]->expression.vtype == TYPE_VECTOR))
979             {
980                 ast_type_to_string(exprs[0], ty1, sizeof(ty1));
981                 ast_type_to_string(exprs[1], ty2, sizeof(ty2));
982                 parseerror(parser, "invalid types used in expression: %s and %s",
983                            ty1, ty2);
984                 return false;
985             }
986             if (ast_istype(exprs[0], ast_entfield))
987                 assignop = type_storep_instr[exprs[0]->expression.vtype];
988             else
989                 assignop = type_store_instr[exprs[0]->expression.vtype];
990             switch (exprs[0]->expression.vtype) {
991                 case TYPE_FLOAT:
992                     out = (ast_expression*)ast_binstore_new(ctx, assignop,
993                                                             (op->id == opid2('*','=') ? INSTR_MUL_F : INSTR_DIV_F),
994                                                             exprs[0], exprs[1]);
995                     break;
996                 case TYPE_VECTOR:
997                     if (op->id == opid2('*','=')) {
998                         out = (ast_expression*)ast_binstore_new(ctx, assignop, INSTR_MUL_VF,
999                                                                 exprs[0], exprs[1]);
1000                     } else {
1001                         /* there's no DIV_VF */
1002                         out = (ast_expression*)ast_binary_new(ctx, INSTR_DIV_F,
1003                                                               (ast_expression*)parser_const_float_1(parser),
1004                                                               exprs[1]);
1005                         if (!out)
1006                             return false;
1007                         out = (ast_expression*)ast_binstore_new(ctx, assignop, INSTR_MUL_VF,
1008                                                                 exprs[0], out);
1009                     }
1010                     break;
1011                 default:
1012                     parseerror(parser, "invalid types used in expression: cannot add or subtract type %s and %s",
1013                                type_name[exprs[0]->expression.vtype],
1014                                type_name[exprs[1]->expression.vtype]);
1015                     return false;
1016             };
1017             break;
1018         case opid2('&','='):
1019         case opid2('|','='):
1020             if (NotSameType(TYPE_FLOAT)) {
1021                 ast_type_to_string(exprs[0], ty1, sizeof(ty1));
1022                 ast_type_to_string(exprs[1], ty2, sizeof(ty2));
1023                 parseerror(parser, "invalid types used in expression: %s and %s",
1024                            ty1, ty2);
1025                 return false;
1026             }
1027             if (ast_istype(exprs[0], ast_entfield))
1028                 assignop = type_storep_instr[exprs[0]->expression.vtype];
1029             else
1030                 assignop = type_store_instr[exprs[0]->expression.vtype];
1031             out = (ast_expression*)ast_binstore_new(ctx, assignop,
1032                                                     (op->id == opid2('&','=') ? INSTR_BITAND : INSTR_BITOR),
1033                                                     exprs[0], exprs[1]);
1034             break;
1035         case opid3('&','~','='):
1036             /* This is like: a &= ~(b);
1037              * But QC has no bitwise-not, so we implement it as
1038              * a -= a & (b);
1039              */
1040             if (NotSameType(TYPE_FLOAT)) {
1041                 ast_type_to_string(exprs[0], ty1, sizeof(ty1));
1042                 ast_type_to_string(exprs[1], ty2, sizeof(ty2));
1043                 parseerror(parser, "invalid types used in expression: %s and %s",
1044                            ty1, ty2);
1045                 return false;
1046             }
1047             if (ast_istype(exprs[0], ast_entfield))
1048                 assignop = type_storep_instr[exprs[0]->expression.vtype];
1049             else
1050                 assignop = type_store_instr[exprs[0]->expression.vtype];
1051             out = (ast_expression*)ast_binary_new(ctx, INSTR_BITAND, exprs[0], exprs[1]);
1052             if (!out)
1053                 return false;
1054             out = (ast_expression*)ast_binstore_new(ctx, assignop, INSTR_SUB_F, exprs[0], out);
1055             break;
1056     }
1057 #undef NotSameType
1058
1059     if (!out) {
1060         parseerror(parser, "failed to apply operand %s", op->op);
1061         return false;
1062     }
1063
1064     DEBUGSHUNTDO(con_out("applied %s\n", op->op));
1065     vec_push(sy->out, syexp(ctx, out));
1066     return true;
1067 }
1068
1069 static bool parser_close_call(parser_t *parser, shunt *sy)
1070 {
1071     /* was a function call */
1072     ast_expression *fun;
1073     ast_call       *call;
1074
1075     size_t          fid;
1076     size_t          paramcount;
1077
1078     vec_shrinkby(sy->ops, 1);
1079     fid = sy->ops[vec_size(sy->ops)].off;
1080
1081     /* out[fid] is the function
1082      * everything above is parameters...
1083      * 0 params = nothing
1084      * 1 params = ast_expression
1085      * more = ast_block
1086      */
1087
1088     if (vec_size(sy->out) < 1 || vec_size(sy->out) <= fid) {
1089         parseerror(parser, "internal error: function call needs function and parameter list...");
1090         return false;
1091     }
1092
1093     fun = sy->out[fid].out;
1094
1095     call = ast_call_new(sy->ops[vec_size(sy->ops)].ctx, fun);
1096     if (!call) {
1097         parseerror(parser, "out of memory");
1098         return false;
1099     }
1100
1101     if (fid+1 == vec_size(sy->out)) {
1102         /* no arguments */
1103         paramcount = 0;
1104     } else if (fid+2 == vec_size(sy->out)) {
1105         ast_block *params;
1106         vec_shrinkby(sy->out, 1);
1107         params = sy->out[vec_size(sy->out)].block;
1108         if (!params) {
1109             /* 1 param */
1110             paramcount = 1;
1111             vec_push(call->params, sy->out[vec_size(sy->out)].out);
1112         } else {
1113             paramcount = vec_size(params->exprs);
1114             call->params = params->exprs;
1115             params->exprs = NULL;
1116             ast_delete(params);
1117         }
1118         if (!ast_call_check_types(call))
1119             parser->errors++;
1120     } else {
1121         parseerror(parser, "invalid function call");
1122         return false;
1123     }
1124
1125     /* overwrite fid, the function, with a call */
1126     sy->out[fid] = syexp(call->expression.node.context, (ast_expression*)call);
1127
1128     if (fun->expression.vtype != TYPE_FUNCTION) {
1129         parseerror(parser, "not a function (%s)", type_name[fun->expression.vtype]);
1130         return false;
1131     }
1132
1133     if (!fun->expression.next) {
1134         parseerror(parser, "could not determine function return type");
1135         return false;
1136     } else {
1137         if (vec_size(fun->expression.params) != paramcount &&
1138             !(fun->expression.variadic &&
1139               vec_size(fun->expression.params) < paramcount))
1140         {
1141             ast_value *fval;
1142             const char *fewmany = (vec_size(fun->expression.params) > paramcount) ? "few" : "many";
1143
1144             fval = (ast_istype(fun, ast_value) ? ((ast_value*)fun) : NULL);
1145             if (opts_standard == COMPILER_GMQCC)
1146             {
1147                 if (fval)
1148                     parseerror(parser, "too %s parameters for call to %s: expected %i, got %i\n"
1149                                " -> `%s` has been declared here: %s:%i",
1150                                fewmany, fval->name, (int)vec_size(fun->expression.params), (int)paramcount,
1151                                fval->name, ast_ctx(fun).file, (int)ast_ctx(fun).line);
1152                 else
1153                     parseerror(parser, "too %s parameters for function call: expected %i, got %i\n"
1154                                " -> `%s` has been declared here: %s:%i",
1155                                fewmany, fval->name, (int)vec_size(fun->expression.params), (int)paramcount,
1156                                fval->name, ast_ctx(fun).file, (int)ast_ctx(fun).line);
1157                 return false;
1158             }
1159             else
1160             {
1161                 if (fval)
1162                     return !parsewarning(parser, WARN_TOO_FEW_PARAMETERS,
1163                                          "too %s parameters for call to %s: expected %i, got %i\n"
1164                                          " -> `%s` has been declared here: %s:%i",
1165                                          fewmany, fval->name, (int)vec_size(fun->expression.params), (int)paramcount,
1166                                          fval->name, ast_ctx(fun).file, (int)ast_ctx(fun).line);
1167                 else
1168                     return !parsewarning(parser, WARN_TOO_FEW_PARAMETERS,
1169                                          "too %s parameters for function call: expected %i, got %i\n"
1170                                          " -> `%s` has been declared here: %s:%i",
1171                                          fewmany, fval->name, (int)vec_size(fun->expression.params), (int)paramcount,
1172                                          fval->name, ast_ctx(fun).file, (int)ast_ctx(fun).line);
1173             }
1174         }
1175     }
1176
1177     return true;
1178 }
1179
1180 static bool parser_close_paren(parser_t *parser, shunt *sy, bool functions_only)
1181 {
1182     if (!vec_size(sy->ops)) {
1183         parseerror(parser, "unmatched closing paren");
1184         return false;
1185     }
1186     /* this would for bit a + (x) because there are no operators inside (x)
1187     if (sy->ops[vec_size(sy->ops)-1].paren == 1) {
1188         parseerror(parser, "empty parenthesis expression");
1189         return false;
1190     }
1191     */
1192     while (vec_size(sy->ops)) {
1193         if (sy->ops[vec_size(sy->ops)-1].paren == SY_PAREN_FUNC) {
1194             if (!parser_close_call(parser, sy))
1195                 return false;
1196             break;
1197         }
1198         if (sy->ops[vec_size(sy->ops)-1].paren == SY_PAREN_EXPR) {
1199             vec_shrinkby(sy->ops, 1);
1200             return !functions_only;
1201         }
1202         if (sy->ops[vec_size(sy->ops)-1].paren == SY_PAREN_INDEX) {
1203             if (functions_only)
1204                 return false;
1205             /* pop off the parenthesis */
1206             vec_shrinkby(sy->ops, 1);
1207             /* then apply the index operator */
1208             if (!parser_sy_pop(parser, sy))
1209                 return false;
1210             return true;
1211         }
1212         if (!parser_sy_pop(parser, sy))
1213             return false;
1214     }
1215     return true;
1216 }
1217
1218 static void parser_reclassify_token(parser_t *parser)
1219 {
1220     size_t i;
1221     for (i = 0; i < operator_count; ++i) {
1222         if (!strcmp(parser_tokval(parser), operators[i].op)) {
1223             parser->tok = TOKEN_OPERATOR;
1224             return;
1225         }
1226     }
1227 }
1228
1229 static ast_expression* parse_expression_leave(parser_t *parser, bool stopatcomma)
1230 {
1231     ast_expression *expr = NULL;
1232     shunt sy;
1233     bool wantop = false;
1234     bool gotmemberof = false;
1235
1236     /* count the parens because an if starts with one, so the
1237      * end of a condition is an unmatched closing paren
1238      */
1239     int parens = 0;
1240     int ternaries = 0;
1241
1242     sy.out = NULL;
1243     sy.ops = NULL;
1244
1245     parser->lex->flags.noops = false;
1246
1247     parser_reclassify_token(parser);
1248
1249     while (true)
1250     {
1251         if (gotmemberof)
1252             gotmemberof = false;
1253         else
1254             parser->memberof = 0;
1255
1256         if (parser->tok == TOKEN_IDENT)
1257         {
1258             ast_expression *var;
1259             if (wantop) {
1260                 parseerror(parser, "expected operator or end of statement");
1261                 goto onerr;
1262             }
1263             wantop = true;
1264             /* variable */
1265             if (opts_standard == COMPILER_GMQCC)
1266             {
1267                 if (parser->memberof == TYPE_ENTITY) {
1268                     /* still get vars first since there could be a fieldpointer */
1269                     var = parser_find_var(parser, parser_tokval(parser));
1270                     if (!var)
1271                         var = parser_find_field(parser, parser_tokval(parser));
1272                 }
1273                 else if (parser->memberof == TYPE_VECTOR)
1274                 {
1275                     parseerror(parser, "TODO: implement effective vector member access");
1276                     goto onerr;
1277                 }
1278                 else if (parser->memberof) {
1279                     parseerror(parser, "namespace for member not found");
1280                     goto onerr;
1281                 }
1282                 else
1283                     var = parser_find_var(parser, parser_tokval(parser));
1284             } else {
1285                 var = parser_find_var(parser, parser_tokval(parser));
1286                 if (!var)
1287                     var = parser_find_field(parser, parser_tokval(parser));
1288             }
1289             if (!var) {
1290                 parseerror(parser, "unexpected ident: %s", parser_tokval(parser));
1291                 goto onerr;
1292             }
1293             if (ast_istype(var, ast_value))
1294                 ((ast_value*)var)->uses++;
1295             vec_push(sy.out, syexp(parser_ctx(parser), var));
1296             DEBUGSHUNTDO(con_out("push %s\n", parser_tokval(parser)));
1297         }
1298         else if (parser->tok == TOKEN_FLOATCONST) {
1299             ast_value *val;
1300             if (wantop) {
1301                 parseerror(parser, "expected operator or end of statement, got constant");
1302                 goto onerr;
1303             }
1304             wantop = true;
1305             val = parser_const_float(parser, (parser_token(parser)->constval.f));
1306             if (!val)
1307                 return false;
1308             vec_push(sy.out, syexp(parser_ctx(parser), (ast_expression*)val));
1309             DEBUGSHUNTDO(con_out("push %g\n", parser_token(parser)->constval.f));
1310         }
1311         else if (parser->tok == TOKEN_INTCONST) {
1312             ast_value *val;
1313             if (wantop) {
1314                 parseerror(parser, "expected operator or end of statement, got constant");
1315                 goto onerr;
1316             }
1317             wantop = true;
1318             val = parser_const_float(parser, (double)(parser_token(parser)->constval.i));
1319             if (!val)
1320                 return false;
1321             vec_push(sy.out, syexp(parser_ctx(parser), (ast_expression*)val));
1322             DEBUGSHUNTDO(con_out("push %i\n", parser_token(parser)->constval.i));
1323         }
1324         else if (parser->tok == TOKEN_STRINGCONST) {
1325             ast_value *val;
1326             if (wantop) {
1327                 parseerror(parser, "expected operator or end of statement, got constant");
1328                 goto onerr;
1329             }
1330             wantop = true;
1331             val = parser_const_string(parser, parser_tokval(parser));
1332             if (!val)
1333                 return false;
1334             vec_push(sy.out, syexp(parser_ctx(parser), (ast_expression*)val));
1335             DEBUGSHUNTDO(con_out("push string\n"));
1336         }
1337         else if (parser->tok == TOKEN_VECTORCONST) {
1338             ast_value *val;
1339             if (wantop) {
1340                 parseerror(parser, "expected operator or end of statement, got constant");
1341                 goto onerr;
1342             }
1343             wantop = true;
1344             val = parser_const_vector(parser, parser_token(parser)->constval.v);
1345             if (!val)
1346                 return false;
1347             vec_push(sy.out, syexp(parser_ctx(parser), (ast_expression*)val));
1348             DEBUGSHUNTDO(con_out("push '%g %g %g'\n",
1349                                 parser_token(parser)->constval.v.x,
1350                                 parser_token(parser)->constval.v.y,
1351                                 parser_token(parser)->constval.v.z));
1352         }
1353         else if (parser->tok == '(') {
1354             parseerror(parser, "internal error: '(' should be classified as operator");
1355             goto onerr;
1356         }
1357         else if (parser->tok == '[') {
1358             parseerror(parser, "internal error: '[' should be classified as operator");
1359             goto onerr;
1360         }
1361         else if (parser->tok == ')') {
1362             if (wantop) {
1363                 DEBUGSHUNTDO(con_out("do[op] )\n"));
1364                 --parens;
1365                 if (parens < 0)
1366                     break;
1367                 /* we do expect an operator next */
1368                 /* closing an opening paren */
1369                 if (!parser_close_paren(parser, &sy, false))
1370                     goto onerr;
1371             } else {
1372                 DEBUGSHUNTDO(con_out("do[nop] )\n"));
1373                 --parens;
1374                 if (parens < 0)
1375                     break;
1376                 /* allowed for function calls */
1377                 if (!parser_close_paren(parser, &sy, true))
1378                     goto onerr;
1379             }
1380             wantop = true;
1381         }
1382         else if (parser->tok == ']') {
1383             if (!wantop)
1384                 parseerror(parser, "operand expected");
1385             --parens;
1386             if (parens < 0)
1387                 break;
1388             if (!parser_close_paren(parser, &sy, false))
1389                 goto onerr;
1390             wantop = true;
1391         }
1392         else if (parser->tok != TOKEN_OPERATOR) {
1393             if (wantop) {
1394                 parseerror(parser, "expected operator or end of statement");
1395                 goto onerr;
1396             }
1397             break;
1398         }
1399         else
1400         {
1401             /* classify the operator */
1402             const oper_info *op;
1403             const oper_info *olast = NULL;
1404             size_t o;
1405             for (o = 0; o < operator_count; ++o) {
1406                 if ((!(operators[o].flags & OP_PREFIX) == wantop) &&
1407                     /* !(operators[o].flags & OP_SUFFIX) && / * remove this */
1408                     !strcmp(parser_tokval(parser), operators[o].op))
1409                 {
1410                     break;
1411                 }
1412             }
1413             if (o == operator_count) {
1414                 /* no operator found... must be the end of the statement */
1415                 break;
1416             }
1417             /* found an operator */
1418             op = &operators[o];
1419
1420             /* when declaring variables, a comma starts a new variable */
1421             if (op->id == opid1(',') && !parens && stopatcomma) {
1422                 /* fixup the token */
1423                 parser->tok = ',';
1424                 break;
1425             }
1426
1427             /* a colon without a pervious question mark cannot be a ternary */
1428             if (!ternaries && op->id == opid2(':','?')) {
1429                 parser->tok = ':';
1430                 break;
1431             }
1432
1433             if (vec_size(sy.ops) && !vec_last(sy.ops).paren)
1434                 olast = &operators[vec_last(sy.ops).etype-1];
1435
1436             while (olast && (
1437                     (op->prec < olast->prec) ||
1438                     (op->assoc == ASSOC_LEFT && op->prec <= olast->prec) ) )
1439             {
1440                 if (!parser_sy_pop(parser, &sy))
1441                     goto onerr;
1442                 if (vec_size(sy.ops) && !vec_last(sy.ops).paren)
1443                     olast = &operators[vec_last(sy.ops).etype-1];
1444                 else
1445                     olast = NULL;
1446             }
1447
1448             if (op->id == opid1('.') && opts_standard == COMPILER_GMQCC) {
1449                 /* for gmqcc standard: open up the namespace of the previous type */
1450                 ast_expression *prevex = vec_last(sy.out).out;
1451                 if (!prevex) {
1452                     parseerror(parser, "unexpected member operator");
1453                     goto onerr;
1454                 }
1455                 if (prevex->expression.vtype == TYPE_ENTITY)
1456                     parser->memberof = TYPE_ENTITY;
1457                 else if (prevex->expression.vtype == TYPE_VECTOR)
1458                     parser->memberof = TYPE_VECTOR;
1459                 else {
1460                     parseerror(parser, "type error: type has no members");
1461                     goto onerr;
1462                 }
1463                 gotmemberof = true;
1464             }
1465
1466             if (op->id == opid1('(')) {
1467                 if (wantop) {
1468                     size_t sycount = vec_size(sy.out);
1469                     DEBUGSHUNTDO(con_out("push [op] (\n"));
1470                     ++parens;
1471                     /* we expected an operator, this is the function-call operator */
1472                     vec_push(sy.ops, syparen(parser_ctx(parser), SY_PAREN_FUNC, sycount-1));
1473                 } else {
1474                     ++parens;
1475                     vec_push(sy.ops, syparen(parser_ctx(parser), SY_PAREN_EXPR, 0));
1476                     DEBUGSHUNTDO(con_out("push [nop] (\n"));
1477                 }
1478                 wantop = false;
1479             } else if (op->id == opid1('[')) {
1480                 if (!wantop) {
1481                     parseerror(parser, "unexpected array subscript");
1482                     goto onerr;
1483                 }
1484                 ++parens;
1485                 /* push both the operator and the paren, this makes life easier */
1486                 vec_push(sy.ops, syop(parser_ctx(parser), op));
1487                 vec_push(sy.ops, syparen(parser_ctx(parser), SY_PAREN_INDEX, 0));
1488                 wantop = false;
1489             } else if (op->id == opid2('?',':')) {
1490                 wantop = false;
1491                 vec_push(sy.ops, syop(parser_ctx(parser), op));
1492                 wantop = false;
1493                 --ternaries;
1494             } else if (op->id == opid2(':','?')) {
1495                 /* we don't push this operator */
1496                 wantop = false;
1497                 ++ternaries;
1498             } else {
1499                 DEBUGSHUNTDO(con_out("push operator %s\n", op->op));
1500                 vec_push(sy.ops, syop(parser_ctx(parser), op));
1501                 wantop = !!(op->flags & OP_SUFFIX);
1502             }
1503         }
1504         if (!parser_next(parser)) {
1505             goto onerr;
1506         }
1507         if (parser->tok == ';' ||
1508             (!parens && parser->tok == ']'))
1509         {
1510             break;
1511         }
1512     }
1513
1514     while (vec_size(sy.ops)) {
1515         if (!parser_sy_pop(parser, &sy))
1516             goto onerr;
1517     }
1518
1519     parser->lex->flags.noops = true;
1520     if (!vec_size(sy.out)) {
1521         parseerror(parser, "empty expression");
1522         expr = NULL;
1523     } else
1524         expr = sy.out[0].out;
1525     vec_free(sy.out);
1526     vec_free(sy.ops);
1527     DEBUGSHUNTDO(con_out("shunt done\n"));
1528     return expr;
1529
1530 onerr:
1531     parser->lex->flags.noops = true;
1532     vec_free(sy.out);
1533     vec_free(sy.ops);
1534     return NULL;
1535 }
1536
1537 static ast_expression* parse_expression(parser_t *parser, bool stopatcomma)
1538 {
1539     ast_expression *e = parse_expression_leave(parser, stopatcomma);
1540     if (!e)
1541         return NULL;
1542     if (!parser_next(parser)) {
1543         ast_delete(e);
1544         return NULL;
1545     }
1546     return e;
1547 }
1548
1549 static bool parse_if(parser_t *parser, ast_block *block, ast_expression **out)
1550 {
1551     ast_ifthen *ifthen;
1552     ast_expression *cond, *ontrue, *onfalse = NULL;
1553     bool ifnot = false;
1554
1555     lex_ctx ctx = parser_ctx(parser);
1556
1557     (void)block; /* not touching */
1558
1559     /* skip the 'if', parse an optional 'not' and check for an opening paren */
1560     if (!parser_next(parser)) {
1561         parseerror(parser, "expected condition or 'not'");
1562         return false;
1563     }
1564     if (parser->tok == TOKEN_KEYWORD && !strcmp(parser_tokval(parser), "not")) {
1565         ifnot = true;
1566         if (!parser_next(parser)) {
1567             parseerror(parser, "expected condition in parenthesis");
1568             return false;
1569         }
1570     }
1571     if (parser->tok != '(') {
1572         parseerror(parser, "expected 'if' condition in parenthesis");
1573         return false;
1574     }
1575     /* parse into the expression */
1576     if (!parser_next(parser)) {
1577         parseerror(parser, "expected 'if' condition after opening paren");
1578         return false;
1579     }
1580     /* parse the condition */
1581     cond = parse_expression_leave(parser, false);
1582     if (!cond)
1583         return false;
1584     /* closing paren */
1585     if (parser->tok != ')') {
1586         parseerror(parser, "expected closing paren after 'if' condition");
1587         ast_delete(cond);
1588         return false;
1589     }
1590     /* parse into the 'then' branch */
1591     if (!parser_next(parser)) {
1592         parseerror(parser, "expected statement for on-true branch of 'if'");
1593         ast_delete(cond);
1594         return false;
1595     }
1596     ontrue = parse_statement_or_block(parser);
1597     if (!ontrue) {
1598         ast_delete(cond);
1599         return false;
1600     }
1601     /* check for an else */
1602     if (!strcmp(parser_tokval(parser), "else")) {
1603         /* parse into the 'else' branch */
1604         if (!parser_next(parser)) {
1605             parseerror(parser, "expected on-false branch after 'else'");
1606             ast_delete(ontrue);
1607             ast_delete(cond);
1608             return false;
1609         }
1610         onfalse = parse_statement_or_block(parser);
1611         if (!onfalse) {
1612             ast_delete(ontrue);
1613             ast_delete(cond);
1614             return false;
1615         }
1616     }
1617
1618     if (ifnot)
1619         ifthen = ast_ifthen_new(ctx, cond, onfalse, ontrue);
1620     else
1621         ifthen = ast_ifthen_new(ctx, cond, ontrue, onfalse);
1622     *out = (ast_expression*)ifthen;
1623     return true;
1624 }
1625
1626 static bool parse_while(parser_t *parser, ast_block *block, ast_expression **out)
1627 {
1628     ast_loop *aloop;
1629     ast_expression *cond, *ontrue;
1630
1631     lex_ctx ctx = parser_ctx(parser);
1632
1633     (void)block; /* not touching */
1634
1635     /* skip the 'while' and check for opening paren */
1636     if (!parser_next(parser) || parser->tok != '(') {
1637         parseerror(parser, "expected 'while' condition in parenthesis");
1638         return false;
1639     }
1640     /* parse into the expression */
1641     if (!parser_next(parser)) {
1642         parseerror(parser, "expected 'while' condition after opening paren");
1643         return false;
1644     }
1645     /* parse the condition */
1646     cond = parse_expression_leave(parser, false);
1647     if (!cond)
1648         return false;
1649     /* closing paren */
1650     if (parser->tok != ')') {
1651         parseerror(parser, "expected closing paren after 'while' condition");
1652         ast_delete(cond);
1653         return false;
1654     }
1655     /* parse into the 'then' branch */
1656     if (!parser_next(parser)) {
1657         parseerror(parser, "expected while-loop body");
1658         ast_delete(cond);
1659         return false;
1660     }
1661     ontrue = parse_statement_or_block(parser);
1662     if (!ontrue) {
1663         ast_delete(cond);
1664         return false;
1665     }
1666
1667     aloop = ast_loop_new(ctx, NULL, cond, NULL, NULL, ontrue);
1668     *out = (ast_expression*)aloop;
1669     return true;
1670 }
1671
1672 static bool parse_dowhile(parser_t *parser, ast_block *block, ast_expression **out)
1673 {
1674     ast_loop *aloop;
1675     ast_expression *cond, *ontrue;
1676
1677     lex_ctx ctx = parser_ctx(parser);
1678
1679     (void)block; /* not touching */
1680
1681     /* skip the 'do' and get the body */
1682     if (!parser_next(parser)) {
1683         parseerror(parser, "expected loop body");
1684         return false;
1685     }
1686     ontrue = parse_statement_or_block(parser);
1687     if (!ontrue)
1688         return false;
1689
1690     /* expect the "while" */
1691     if (parser->tok != TOKEN_KEYWORD ||
1692         strcmp(parser_tokval(parser), "while"))
1693     {
1694         parseerror(parser, "expected 'while' and condition");
1695         ast_delete(ontrue);
1696         return false;
1697     }
1698
1699     /* skip the 'while' and check for opening paren */
1700     if (!parser_next(parser) || parser->tok != '(') {
1701         parseerror(parser, "expected 'while' condition in parenthesis");
1702         ast_delete(ontrue);
1703         return false;
1704     }
1705     /* parse into the expression */
1706     if (!parser_next(parser)) {
1707         parseerror(parser, "expected 'while' condition after opening paren");
1708         ast_delete(ontrue);
1709         return false;
1710     }
1711     /* parse the condition */
1712     cond = parse_expression_leave(parser, false);
1713     if (!cond)
1714         return false;
1715     /* closing paren */
1716     if (parser->tok != ')') {
1717         parseerror(parser, "expected closing paren after 'while' condition");
1718         ast_delete(ontrue);
1719         ast_delete(cond);
1720         return false;
1721     }
1722     /* parse on */
1723     if (!parser_next(parser) || parser->tok != ';') {
1724         parseerror(parser, "expected semicolon after condition");
1725         ast_delete(ontrue);
1726         ast_delete(cond);
1727         return false;
1728     }
1729
1730     if (!parser_next(parser)) {
1731         parseerror(parser, "parse error");
1732         ast_delete(ontrue);
1733         ast_delete(cond);
1734         return false;
1735     }
1736
1737     aloop = ast_loop_new(ctx, NULL, NULL, cond, NULL, ontrue);
1738     *out = (ast_expression*)aloop;
1739     return true;
1740 }
1741
1742 static bool parse_for(parser_t *parser, ast_block *block, ast_expression **out)
1743 {
1744     ast_loop *aloop;
1745     ast_expression *initexpr, *cond, *increment, *ontrue;
1746     size_t oldblocklocal;
1747     bool   retval = true;
1748
1749     lex_ctx ctx = parser_ctx(parser);
1750
1751     oldblocklocal = parser->blocklocal;
1752     parser->blocklocal = vec_size(parser->locals);
1753
1754     initexpr  = NULL;
1755     cond      = NULL;
1756     increment = NULL;
1757     ontrue    = NULL;
1758
1759     /* skip the 'while' and check for opening paren */
1760     if (!parser_next(parser) || parser->tok != '(') {
1761         parseerror(parser, "expected 'for' expressions in parenthesis");
1762         goto onerr;
1763     }
1764     /* parse into the expression */
1765     if (!parser_next(parser)) {
1766         parseerror(parser, "expected 'for' initializer after opening paren");
1767         goto onerr;
1768     }
1769
1770     if (parser->tok == TOKEN_TYPENAME) {
1771         if (opts_standard != COMPILER_GMQCC) {
1772             if (parsewarning(parser, WARN_EXTENSIONS,
1773                              "current standard does not allow variable declarations in for-loop initializers"))
1774                 goto onerr;
1775         }
1776
1777         parseerror(parser, "TODO: assignment of new variables to be non-const");
1778         goto onerr;
1779         if (!parse_variable(parser, block, true, false))
1780             goto onerr;
1781     }
1782     else if (parser->tok != ';')
1783     {
1784         initexpr = parse_expression_leave(parser, false);
1785         if (!initexpr)
1786             goto onerr;
1787     }
1788
1789     /* move on to condition */
1790     if (parser->tok != ';') {
1791         parseerror(parser, "expected semicolon after for-loop initializer");
1792         goto onerr;
1793     }
1794     if (!parser_next(parser)) {
1795         parseerror(parser, "expected for-loop condition");
1796         goto onerr;
1797     }
1798
1799     /* parse the condition */
1800     if (parser->tok != ';') {
1801         cond = parse_expression_leave(parser, false);
1802         if (!cond)
1803             goto onerr;
1804     }
1805
1806     /* move on to incrementor */
1807     if (parser->tok != ';') {
1808         parseerror(parser, "expected semicolon after for-loop initializer");
1809         goto onerr;
1810     }
1811     if (!parser_next(parser)) {
1812         parseerror(parser, "expected for-loop condition");
1813         goto onerr;
1814     }
1815
1816     /* parse the incrementor */
1817     if (parser->tok != ')') {
1818         increment = parse_expression_leave(parser, false);
1819         if (!increment)
1820             goto onerr;
1821         if (!ast_istype(increment, ast_store) &&
1822             !ast_istype(increment, ast_call) &&
1823             !ast_istype(increment, ast_binstore))
1824         {
1825             if (genwarning(ast_ctx(increment), WARN_EFFECTLESS_STATEMENT, "statement has no effect"))
1826                 goto onerr;
1827         }
1828     }
1829
1830     /* closing paren */
1831     if (parser->tok != ')') {
1832         parseerror(parser, "expected closing paren after 'for-loop' incrementor");
1833         goto onerr;
1834     }
1835     /* parse into the 'then' branch */
1836     if (!parser_next(parser)) {
1837         parseerror(parser, "expected for-loop body");
1838         goto onerr;
1839     }
1840     ontrue = parse_statement_or_block(parser);
1841     if (!ontrue) {
1842         goto onerr;
1843     }
1844
1845     aloop = ast_loop_new(ctx, initexpr, cond, NULL, increment, ontrue);
1846     *out = (ast_expression*)aloop;
1847
1848     while (vec_size(parser->locals) > parser->blocklocal)
1849         retval = retval && parser_pop_local(parser);
1850     parser->blocklocal = oldblocklocal;
1851     return retval;
1852 onerr:
1853     if (initexpr)  ast_delete(initexpr);
1854     if (cond)      ast_delete(cond);
1855     if (increment) ast_delete(increment);
1856     while (vec_size(parser->locals) > parser->blocklocal)
1857         (void)!parser_pop_local(parser);
1858     parser->blocklocal = oldblocklocal;
1859     return false;
1860 }
1861
1862 static bool parse_return(parser_t *parser, ast_block *block, ast_expression **out)
1863 {
1864     ast_expression *exp = NULL;
1865     ast_return     *ret = NULL;
1866     ast_value      *expected = parser->function->vtype;
1867
1868     (void)block; /* not touching */
1869
1870     if (!parser_next(parser)) {
1871         parseerror(parser, "expected return expression");
1872         return false;
1873     }
1874
1875     if (parser->tok != ';') {
1876         exp = parse_expression(parser, false);
1877         if (!exp)
1878             return false;
1879
1880         if (exp->expression.vtype != expected->expression.next->expression.vtype) {
1881             parseerror(parser, "return with invalid expression");
1882         }
1883
1884         ret = ast_return_new(exp->expression.node.context, exp);
1885         if (!ret) {
1886             ast_delete(exp);
1887             return false;
1888         }
1889     } else {
1890         if (!parser_next(parser))
1891             parseerror(parser, "parse error");
1892         if (expected->expression.next->expression.vtype != TYPE_VOID) {
1893             if (opts_standard != COMPILER_GMQCC)
1894                 (void)!parsewarning(parser, WARN_MISSING_RETURN_VALUES, "return without value");
1895             else
1896                 parseerror(parser, "return without value");
1897         }
1898         ret = ast_return_new(parser_ctx(parser), NULL);
1899     }
1900     *out = (ast_expression*)ret;
1901     return true;
1902 }
1903
1904 static bool parse_break_continue(parser_t *parser, ast_block *block, ast_expression **out, bool is_continue)
1905 {
1906     lex_ctx ctx = parser_ctx(parser);
1907
1908     (void)block; /* not touching */
1909
1910     if (!parser_next(parser) || parser->tok != ';') {
1911         parseerror(parser, "expected semicolon");
1912         return false;
1913     }
1914
1915     if (!parser_next(parser))
1916         parseerror(parser, "parse error");
1917
1918     *out = (ast_expression*)ast_breakcont_new(ctx, is_continue);
1919     return true;
1920 }
1921
1922 static bool parse_switch(parser_t *parser, ast_block *block, ast_expression **out)
1923 {
1924     ast_expression *operand;
1925     ast_value      *opval;
1926     ast_switch     *switchnode;
1927     ast_switch_case swcase;
1928
1929     lex_ctx ctx = parser_ctx(parser);
1930
1931     (void)block; /* not touching */
1932
1933     /* parse over the opening paren */
1934     if (!parser_next(parser) || parser->tok != '(') {
1935         parseerror(parser, "expected switch operand in parenthesis");
1936         return false;
1937     }
1938
1939     /* parse into the expression */
1940     if (!parser_next(parser)) {
1941         parseerror(parser, "expected switch operand");
1942         return false;
1943     }
1944     /* parse the operand */
1945     operand = parse_expression_leave(parser, false);
1946     if (!operand)
1947         return false;
1948
1949     if (!OPTS_FLAG(RELAXED_SWITCH)) {
1950         opval = (ast_value*)operand;
1951         if (!ast_istype(operand, ast_value) || !opval->isconst) {
1952             parseerror(parser, "case on non-constant values need to be explicitly enabled via -frelaxed-switch");
1953             ast_unref(operand);
1954             return false;
1955         }
1956     }
1957
1958     switchnode = ast_switch_new(ctx, operand);
1959
1960     /* closing paren */
1961     if (parser->tok != ')') {
1962         ast_delete(switchnode);
1963         parseerror(parser, "expected closing paren after 'switch' operand");
1964         return false;
1965     }
1966
1967     /* parse over the opening paren */
1968     if (!parser_next(parser) || parser->tok != '{') {
1969         ast_delete(switchnode);
1970         parseerror(parser, "expected list of cases");
1971         return false;
1972     }
1973
1974     if (!parser_next(parser)) {
1975         ast_delete(switchnode);
1976         parseerror(parser, "expected 'case' or 'default'");
1977         return false;
1978     }
1979
1980     /* case list! */
1981     while (parser->tok != '}') {
1982         ast_block *caseblock;
1983
1984         if (parser->tok != TOKEN_KEYWORD) {
1985             ast_delete(switchnode);
1986             parseerror(parser, "expected 'case' or 'default'");
1987             return false;
1988         }
1989         if (!strcmp(parser_tokval(parser), "case")) {
1990             if (!parser_next(parser)) {
1991                 ast_delete(switchnode);
1992                 parseerror(parser, "expected expression for case");
1993                 return false;
1994             }
1995             swcase.value = parse_expression_leave(parser, false);
1996             if (!swcase.value) {
1997                 ast_delete(switchnode);
1998                 parseerror(parser, "expected expression for case");
1999                 return false;
2000             }
2001         }
2002         else if (!strcmp(parser_tokval(parser), "default")) {
2003             swcase.value = NULL;
2004             if (!parser_next(parser)) {
2005                 ast_delete(switchnode);
2006                 parseerror(parser, "expected colon");
2007                 return false;
2008             }
2009         }
2010
2011         /* Now the colon and body */
2012         if (parser->tok != ':') {
2013             if (swcase.value) ast_unref(swcase.value);
2014             ast_delete(switchnode);
2015             parseerror(parser, "expected colon");
2016             return false;
2017         }
2018
2019         if (!parser_next(parser)) {
2020             if (swcase.value) ast_unref(swcase.value);
2021             ast_delete(switchnode);
2022             parseerror(parser, "expected statements or case");
2023             return false;
2024         }
2025         caseblock = ast_block_new(parser_ctx(parser));
2026         if (!caseblock) {
2027             if (swcase.value) ast_unref(swcase.value);
2028             ast_delete(switchnode);
2029             return false;
2030         }
2031         swcase.code = (ast_expression*)caseblock;
2032         vec_push(switchnode->cases, swcase);
2033         while (true) {
2034             ast_expression *expr;
2035             if (parser->tok == '}')
2036                 break;
2037             if (parser->tok == TOKEN_KEYWORD) {
2038                 if (!strcmp(parser_tokval(parser), "case") ||
2039                     !strcmp(parser_tokval(parser), "default"))
2040                 {
2041                     break;
2042                 }
2043             }
2044             if (!parse_statement(parser, caseblock, &expr, true)) {
2045                 ast_delete(switchnode);
2046                 return false;
2047             }
2048             if (!expr)
2049                 continue;
2050             vec_push(caseblock->exprs, expr);
2051         }
2052     }
2053
2054     /* closing paren */
2055     if (parser->tok != '}') {
2056         ast_delete(switchnode);
2057         parseerror(parser, "expected closing paren of case list");
2058         return false;
2059     }
2060     if (!parser_next(parser)) {
2061         ast_delete(switchnode);
2062         parseerror(parser, "parse error after switch");
2063         return false;
2064     }
2065     *out = (ast_expression*)switchnode;
2066     return true;
2067 }
2068
2069 static bool parse_statement(parser_t *parser, ast_block *block, ast_expression **out, bool allow_cases)
2070 {
2071     if (parser->tok == TOKEN_TYPENAME || parser->tok == '.')
2072     {
2073         /* local variable */
2074         if (!block) {
2075             parseerror(parser, "cannot declare a variable from here");
2076             return false;
2077         }
2078         if (opts_standard == COMPILER_QCC) {
2079             if (parsewarning(parser, WARN_EXTENSIONS, "missing 'local' keyword when declaring a local variable"))
2080                 return false;
2081         }
2082         if (!parse_variable(parser, block, false, false))
2083             return false;
2084         *out = NULL;
2085         return true;
2086     }
2087     else if (parser->tok == TOKEN_KEYWORD)
2088     {
2089         if (!strcmp(parser_tokval(parser), "local"))
2090         {
2091             if (!block) {
2092                 parseerror(parser, "cannot declare a local variable here");
2093                 return false;
2094             }
2095             if (!parser_next(parser)) {
2096                 parseerror(parser, "expected variable declaration");
2097                 return false;
2098             }
2099             if (!parse_variable(parser, block, true, false))
2100                 return false;
2101             *out = NULL;
2102             return true;
2103         }
2104         else if (!strcmp(parser_tokval(parser), "return"))
2105         {
2106             return parse_return(parser, block, out);
2107         }
2108         else if (!strcmp(parser_tokval(parser), "if"))
2109         {
2110             return parse_if(parser, block, out);
2111         }
2112         else if (!strcmp(parser_tokval(parser), "while"))
2113         {
2114             return parse_while(parser, block, out);
2115         }
2116         else if (!strcmp(parser_tokval(parser), "do"))
2117         {
2118             return parse_dowhile(parser, block, out);
2119         }
2120         else if (!strcmp(parser_tokval(parser), "for"))
2121         {
2122             if (opts_standard == COMPILER_QCC) {
2123                 if (parsewarning(parser, WARN_EXTENSIONS, "for loops are not recognized in the original Quake C standard, to enable try an alternate standard --std=?"))
2124                     return false;
2125             }
2126             return parse_for(parser, block, out);
2127         }
2128         else if (!strcmp(parser_tokval(parser), "break"))
2129         {
2130             return parse_break_continue(parser, block, out, false);
2131         }
2132         else if (!strcmp(parser_tokval(parser), "continue"))
2133         {
2134             return parse_break_continue(parser, block, out, true);
2135         }
2136         else if (!strcmp(parser_tokval(parser), "switch"))
2137         {
2138             return parse_switch(parser, block, out);
2139         }
2140         else if (!strcmp(parser_tokval(parser), "case") ||
2141                  !strcmp(parser_tokval(parser), "default"))
2142         {
2143             if (!allow_cases) {
2144                 parseerror(parser, "unexpected 'case' label");
2145                 return false;
2146             }
2147             return true;
2148         }
2149         parseerror(parser, "Unexpected keyword");
2150         return false;
2151     }
2152     else if (parser->tok == '{')
2153     {
2154         ast_block *inner;
2155         inner = parse_block(parser, false);
2156         if (!inner)
2157             return false;
2158         *out = (ast_expression*)inner;
2159         return true;
2160     }
2161     else
2162     {
2163         ast_expression *exp = parse_expression(parser, false);
2164         if (!exp)
2165             return false;
2166         *out = exp;
2167         if (!ast_istype(exp, ast_store) &&
2168             !ast_istype(exp, ast_call) &&
2169             !ast_istype(exp, ast_binstore))
2170         {
2171             if (genwarning(ast_ctx(exp), WARN_EFFECTLESS_STATEMENT, "statement has no effect"))
2172                 return false;
2173         }
2174         return true;
2175     }
2176 }
2177
2178 static bool GMQCC_WARN parser_pop_local(parser_t *parser)
2179 {
2180     bool rv = true;
2181     varentry_t *ve;
2182
2183     ve = &vec_last(parser->locals);
2184     if (!parser->errors) {
2185         if (ast_istype(ve->var, ast_value) && !(((ast_value*)(ve->var))->uses)) {
2186             if (parsewarning(parser, WARN_UNUSED_VARIABLE, "unused variable: `%s`", ve->name))
2187                 rv = false;
2188         }
2189     }
2190     mem_d(ve->name);
2191     vec_pop(parser->locals);
2192     return rv;
2193 }
2194
2195 static bool parse_block_into(parser_t *parser, ast_block *block, bool warnreturn)
2196 {
2197     size_t oldblocklocal;
2198     bool   retval = true;
2199
2200     oldblocklocal = parser->blocklocal;
2201     parser->blocklocal = vec_size(parser->locals);
2202
2203     if (!parser_next(parser)) { /* skip the '{' */
2204         parseerror(parser, "expected function body");
2205         goto cleanup;
2206     }
2207
2208     while (parser->tok != TOKEN_EOF && parser->tok < TOKEN_ERROR)
2209     {
2210         ast_expression *expr;
2211         if (parser->tok == '}')
2212             break;
2213
2214         if (!parse_statement(parser, block, &expr, false)) {
2215             /* parseerror(parser, "parse error"); */
2216             block = NULL;
2217             goto cleanup;
2218         }
2219         if (!expr)
2220             continue;
2221         vec_push(block->exprs, expr);
2222     }
2223
2224     if (parser->tok != '}') {
2225         block = NULL;
2226     } else {
2227         if (warnreturn && parser->function->vtype->expression.next->expression.vtype != TYPE_VOID)
2228         {
2229             if (!vec_size(block->exprs) ||
2230                 !ast_istype(vec_last(block->exprs), ast_return))
2231             {
2232                 if (parsewarning(parser, WARN_MISSING_RETURN_VALUES, "control reaches end of non-void function")) {
2233                     block = NULL;
2234                     goto cleanup;
2235                 }
2236             }
2237         }
2238         (void)parser_next(parser);
2239     }
2240
2241 cleanup:
2242     while (vec_size(parser->locals) > parser->blocklocal)
2243         retval = retval && parser_pop_local(parser);
2244     parser->blocklocal = oldblocklocal;
2245     return !!block;
2246 }
2247
2248 static ast_block* parse_block(parser_t *parser, bool warnreturn)
2249 {
2250     ast_block *block;
2251     block = ast_block_new(parser_ctx(parser));
2252     if (!block)
2253         return NULL;
2254     if (!parse_block_into(parser, block, warnreturn)) {
2255         ast_block_delete(block);
2256         return NULL;
2257     }
2258     return block;
2259 }
2260
2261 static ast_expression* parse_statement_or_block(parser_t *parser)
2262 {
2263     ast_expression *expr = NULL;
2264     if (parser->tok == '{')
2265         return (ast_expression*)parse_block(parser, false);
2266     if (!parse_statement(parser, NULL, &expr, false))
2267         return NULL;
2268     return expr;
2269 }
2270
2271 /* loop method */
2272 static bool create_vector_members(ast_value *var, varentry_t *ve)
2273 {
2274     size_t i;
2275     size_t len = strlen(var->name);
2276
2277     for (i = 0; i < 3; ++i) {
2278         ve[i].var = (ast_expression*)ast_member_new(ast_ctx(var), (ast_expression*)var, i);
2279         if (!ve[i].var)
2280             break;
2281
2282         ve[i].name = (char*)mem_a(len+3);
2283         if (!ve[i].name) {
2284             ast_delete(ve[i].var);
2285             break;
2286         }
2287
2288         memcpy(ve[i].name, var->name, len);
2289         ve[i].name[len]   = '_';
2290         ve[i].name[len+1] = 'x'+i;
2291         ve[i].name[len+2] = 0;
2292     }
2293     if (i == 3)
2294         return true;
2295
2296     /* unroll */
2297     do {
2298         --i;
2299         mem_d(ve[i].name);
2300         ast_delete(ve[i].var);
2301         ve[i].name = NULL;
2302         ve[i].var  = NULL;
2303     } while (i);
2304     return false;
2305 }
2306
2307 static bool parse_function_body(parser_t *parser, ast_value *var)
2308 {
2309     ast_block      *block = NULL;
2310     ast_function   *func;
2311     ast_function   *old;
2312     size_t          parami;
2313
2314     ast_expression *framenum  = NULL;
2315     ast_expression *nextthink = NULL;
2316     /* None of the following have to be deleted */
2317     ast_expression *fld_think = NULL, *fld_nextthink = NULL, *fld_frame = NULL;
2318     ast_expression *gbl_time = NULL, *gbl_self = NULL;
2319     bool            has_frame_think;
2320
2321     bool retval = true;
2322
2323     has_frame_think = false;
2324     old = parser->function;
2325
2326     if (var->expression.variadic) {
2327         if (parsewarning(parser, WARN_VARIADIC_FUNCTION,
2328                          "variadic function with implementation will not be able to access additional parameters"))
2329         {
2330             return false;
2331         }
2332     }
2333
2334     if (parser->tok == '[') {
2335         /* got a frame definition: [ framenum, nextthink ]
2336          * this translates to:
2337          * self.frame = framenum;
2338          * self.nextthink = time + 0.1;
2339          * self.think = nextthink;
2340          */
2341         nextthink = NULL;
2342
2343         fld_think     = parser_find_field(parser, "think");
2344         fld_nextthink = parser_find_field(parser, "nextthink");
2345         fld_frame     = parser_find_field(parser, "frame");
2346         if (!fld_think || !fld_nextthink || !fld_frame) {
2347             parseerror(parser, "cannot use [frame,think] notation without the required fields");
2348             parseerror(parser, "please declare the following entityfields: `frame`, `think`, `nextthink`");
2349             return false;
2350         }
2351         gbl_time      = parser_find_global(parser, "time");
2352         gbl_self      = parser_find_global(parser, "self");
2353         if (!gbl_time || !gbl_self) {
2354             parseerror(parser, "cannot use [frame,think] notation without the required globals");
2355             parseerror(parser, "please declare the following globals: `time`, `self`");
2356             return false;
2357         }
2358
2359         if (!parser_next(parser))
2360             return false;
2361
2362         framenum = parse_expression_leave(parser, true);
2363         if (!framenum) {
2364             parseerror(parser, "expected a framenumber constant in[frame,think] notation");
2365             return false;
2366         }
2367         if (!ast_istype(framenum, ast_value) || !( (ast_value*)framenum )->isconst) {
2368             ast_unref(framenum);
2369             parseerror(parser, "framenumber in [frame,think] notation must be a constant");
2370             return false;
2371         }
2372
2373         if (parser->tok != ',') {
2374             ast_unref(framenum);
2375             parseerror(parser, "expected comma after frame number in [frame,think] notation");
2376             parseerror(parser, "Got a %i\n", parser->tok);
2377             return false;
2378         }
2379
2380         if (!parser_next(parser)) {
2381             ast_unref(framenum);
2382             return false;
2383         }
2384
2385         if (parser->tok == TOKEN_IDENT && !parser_find_var(parser, parser_tokval(parser)))
2386         {
2387             /* qc allows the use of not-yet-declared functions here
2388              * - this automatically creates a prototype */
2389             varentry_t      varent;
2390             ast_value      *thinkfunc;
2391             ast_expression *functype = fld_think->expression.next;
2392
2393             thinkfunc = ast_value_new(parser_ctx(parser), parser_tokval(parser), functype->expression.vtype);
2394             if (!thinkfunc || !ast_type_adopt(thinkfunc, functype)) {
2395                 ast_unref(framenum);
2396                 parseerror(parser, "failed to create implicit prototype for `%s`", parser_tokval(parser));
2397                 return false;
2398             }
2399
2400             if (!parser_next(parser)) {
2401                 ast_unref(framenum);
2402                 ast_delete(thinkfunc);
2403                 return false;
2404             }
2405
2406             varent.var = (ast_expression*)thinkfunc;
2407             varent.name = util_strdup(thinkfunc->name);
2408             vec_push(parser->globals, varent);
2409             nextthink = (ast_expression*)thinkfunc;
2410
2411         } else {
2412             nextthink = parse_expression_leave(parser, true);
2413             if (!nextthink) {
2414                 ast_unref(framenum);
2415                 parseerror(parser, "expected a think-function in [frame,think] notation");
2416                 return false;
2417             }
2418         }
2419
2420         if (!ast_istype(nextthink, ast_value)) {
2421             parseerror(parser, "think-function in [frame,think] notation must be a constant");
2422             retval = false;
2423         }
2424
2425         if (retval && parser->tok != ']') {
2426             parseerror(parser, "expected closing `]` for [frame,think] notation");
2427             retval = false;
2428         }
2429
2430         if (retval && !parser_next(parser)) {
2431             retval = false;
2432         }
2433
2434         if (retval && parser->tok != '{') {
2435             parseerror(parser, "a function body has to be declared after a [frame,think] declaration");
2436             retval = false;
2437         }
2438
2439         if (!retval) {
2440             ast_unref(nextthink);
2441             ast_unref(framenum);
2442             return false;
2443         }
2444
2445         has_frame_think = true;
2446     }
2447
2448     block = ast_block_new(parser_ctx(parser));
2449     if (!block) {
2450         parseerror(parser, "failed to allocate block");
2451         if (has_frame_think) {
2452             ast_unref(nextthink);
2453             ast_unref(framenum);
2454         }
2455         return false;
2456     }
2457
2458     if (has_frame_think) {
2459         lex_ctx ctx;
2460         ast_expression *self_frame;
2461         ast_expression *self_nextthink;
2462         ast_expression *self_think;
2463         ast_expression *time_plus_1;
2464         ast_store *store_frame;
2465         ast_store *store_nextthink;
2466         ast_store *store_think;
2467
2468         ctx = parser_ctx(parser);
2469         self_frame     = (ast_expression*)ast_entfield_new(ctx, gbl_self, fld_frame);
2470         self_nextthink = (ast_expression*)ast_entfield_new(ctx, gbl_self, fld_nextthink);
2471         self_think     = (ast_expression*)ast_entfield_new(ctx, gbl_self, fld_think);
2472
2473         time_plus_1    = (ast_expression*)ast_binary_new(ctx, INSTR_ADD_F,
2474                          gbl_time, (ast_expression*)parser_const_float(parser, 0.1));
2475
2476         if (!self_frame || !self_nextthink || !self_think || !time_plus_1) {
2477             if (self_frame)     ast_delete(self_frame);
2478             if (self_nextthink) ast_delete(self_nextthink);
2479             if (self_think)     ast_delete(self_think);
2480             if (time_plus_1)    ast_delete(time_plus_1);
2481             retval = false;
2482         }
2483
2484         if (retval)
2485         {
2486             store_frame     = ast_store_new(ctx, INSTR_STOREP_F,   self_frame,     framenum);
2487             store_nextthink = ast_store_new(ctx, INSTR_STOREP_F,   self_nextthink, time_plus_1);
2488             store_think     = ast_store_new(ctx, INSTR_STOREP_FNC, self_think,     nextthink);
2489
2490             if (!store_frame) {
2491                 ast_delete(self_frame);
2492                 retval = false;
2493             }
2494             if (!store_nextthink) {
2495                 ast_delete(self_nextthink);
2496                 retval = false;
2497             }
2498             if (!store_think) {
2499                 ast_delete(self_think);
2500                 retval = false;
2501             }
2502             if (!retval) {
2503                 if (store_frame)     ast_delete(store_frame);
2504                 if (store_nextthink) ast_delete(store_nextthink);
2505                 if (store_think)     ast_delete(store_think);
2506                 retval = false;
2507             }
2508             vec_push(block->exprs, (ast_expression*)store_frame);
2509             vec_push(block->exprs, (ast_expression*)store_nextthink);
2510             vec_push(block->exprs, (ast_expression*)store_think);
2511         }
2512
2513         if (!retval) {
2514             parseerror(parser, "failed to generate code for [frame,think]");
2515             ast_unref(nextthink);
2516             ast_unref(framenum);
2517             ast_delete(block);
2518             return false;
2519         }
2520     }
2521
2522     for (parami = 0; parami < vec_size(var->expression.params); ++parami) {
2523         size_t     e;
2524         varentry_t ve[3];
2525         ast_value *param = var->expression.params[parami];
2526
2527         if (param->expression.vtype != TYPE_VECTOR &&
2528             (param->expression.vtype != TYPE_FIELD ||
2529              param->expression.next->expression.vtype != TYPE_VECTOR))
2530         {
2531             continue;
2532         }
2533
2534         if (!create_vector_members(param, ve)) {
2535             ast_block_delete(block);
2536             return false;
2537         }
2538
2539         for (e = 0; e < 3; ++e) {
2540             vec_push(parser->locals, ve[e]);
2541             ast_block_collect(block, ve[e].var);
2542             ve[e].var = NULL; /* collected */
2543         }
2544     }
2545
2546     func = ast_function_new(ast_ctx(var), var->name, var);
2547     if (!func) {
2548         parseerror(parser, "failed to allocate function for `%s`", var->name);
2549         ast_block_delete(block);
2550         goto enderr;
2551     }
2552     vec_push(parser->functions, func);
2553
2554     parser->function = func;
2555     if (!parse_block_into(parser, block, true)) {
2556         ast_block_delete(block);
2557         goto enderrfn;
2558     }
2559
2560     vec_push(func->blocks, block);
2561
2562     parser->function = old;
2563     while (vec_size(parser->locals))
2564         retval = retval && parser_pop_local(parser);
2565
2566     if (parser->tok == ';')
2567         return parser_next(parser);
2568     else if (opts_standard == COMPILER_QCC)
2569         parseerror(parser, "missing semicolon after function body (mandatory with -std=qcc)");
2570     return retval;
2571
2572 enderrfn:
2573     vec_pop(parser->functions);
2574     ast_function_delete(func);
2575     var->constval.vfunc = NULL;
2576
2577 enderr:
2578     while (vec_size(parser->locals)) {
2579         mem_d(vec_last(parser->locals).name);
2580         vec_pop(parser->locals);
2581     }
2582     parser->function = old;
2583     return false;
2584 }
2585
2586 static ast_expression *array_accessor_split(
2587     parser_t  *parser,
2588     ast_value *array,
2589     ast_value *index,
2590     size_t     middle,
2591     ast_expression *left,
2592     ast_expression *right
2593     )
2594 {
2595     ast_ifthen *ifthen;
2596     ast_binary *cmp;
2597
2598     lex_ctx ctx = ast_ctx(array);
2599
2600     if (!left || !right) {
2601         if (left)  ast_delete(left);
2602         if (right) ast_delete(right);
2603         return NULL;
2604     }
2605
2606     cmp = ast_binary_new(ctx, INSTR_LT,
2607                          (ast_expression*)index,
2608                          (ast_expression*)parser_const_float(parser, middle));
2609     if (!cmp) {
2610         ast_delete(left);
2611         ast_delete(right);
2612         parseerror(parser, "internal error: failed to create comparison for array setter");
2613         return NULL;
2614     }
2615
2616     ifthen = ast_ifthen_new(ctx, (ast_expression*)cmp, left, right);
2617     if (!ifthen) {
2618         ast_delete(cmp); /* will delete left and right */
2619         parseerror(parser, "internal error: failed to create conditional jump for array setter");
2620         return NULL;
2621     }
2622
2623     return (ast_expression*)ifthen;
2624 }
2625
2626 static ast_expression *array_setter_node(parser_t *parser, ast_value *array, ast_value *index, ast_value *value, size_t from, size_t afterend)
2627 {
2628     lex_ctx ctx = ast_ctx(array);
2629
2630     if (from+1 == afterend) {
2631         /* set this value */
2632         ast_block       *block;
2633         ast_return      *ret;
2634         ast_array_index *subscript;
2635         ast_store       *st;
2636         int assignop = type_store_instr[value->expression.vtype];
2637
2638         if (value->expression.vtype == TYPE_FIELD && value->expression.next->expression.vtype == TYPE_VECTOR)
2639             assignop = INSTR_STORE_V;
2640
2641         subscript = ast_array_index_new(ctx, (ast_expression*)array, (ast_expression*)parser_const_float(parser, from));
2642         if (!subscript)
2643             return NULL;
2644
2645         st = ast_store_new(ctx, assignop, (ast_expression*)subscript, (ast_expression*)value);
2646         if (!st) {
2647             ast_delete(subscript);
2648             return NULL;
2649         }
2650
2651         block = ast_block_new(ctx);
2652         if (!block) {
2653             ast_delete(st);
2654             return NULL;
2655         }
2656
2657         vec_push(block->exprs, (ast_expression*)st);
2658
2659         ret = ast_return_new(ctx, NULL);
2660         if (!ret) {
2661             ast_delete(block);
2662             return NULL;
2663         }
2664
2665         vec_push(block->exprs, (ast_expression*)ret);
2666
2667         return (ast_expression*)block;
2668     } else {
2669         ast_expression *left, *right;
2670         size_t diff = afterend - from;
2671         size_t middle = from + diff/2;
2672         left  = array_setter_node(parser, array, index, value, from, middle);
2673         right = array_setter_node(parser, array, index, value, middle, afterend);
2674         return array_accessor_split(parser, array, index, middle, left, right);
2675     }
2676 }
2677
2678 static ast_expression *array_field_setter_node(
2679     parser_t  *parser,
2680     ast_value *array,
2681     ast_value *entity,
2682     ast_value *index,
2683     ast_value *value,
2684     size_t     from,
2685     size_t     afterend)
2686 {
2687     lex_ctx ctx = ast_ctx(array);
2688
2689     if (from+1 == afterend) {
2690         /* set this value */
2691         ast_block       *block;
2692         ast_return      *ret;
2693         ast_entfield    *entfield;
2694         ast_array_index *subscript;
2695         ast_store       *st;
2696         int assignop = type_storep_instr[value->expression.vtype];
2697
2698         if (value->expression.vtype == TYPE_FIELD && value->expression.next->expression.vtype == TYPE_VECTOR)
2699             assignop = INSTR_STOREP_V;
2700
2701         subscript = ast_array_index_new(ctx, (ast_expression*)array, (ast_expression*)parser_const_float(parser, from));
2702         if (!subscript)
2703             return NULL;
2704
2705         entfield = ast_entfield_new_force(ctx,
2706                                           (ast_expression*)entity,
2707                                           (ast_expression*)subscript,
2708                                           (ast_expression*)subscript);
2709         if (!entfield) {
2710             ast_delete(subscript);
2711             return NULL;
2712         }
2713
2714         st = ast_store_new(ctx, assignop, (ast_expression*)entfield, (ast_expression*)value);
2715         if (!st) {
2716             ast_delete(entfield);
2717             return NULL;
2718         }
2719
2720         block = ast_block_new(ctx);
2721         if (!block) {
2722             ast_delete(st);
2723             return NULL;
2724         }
2725
2726         vec_push(block->exprs, (ast_expression*)st);
2727
2728         ret = ast_return_new(ctx, NULL);
2729         if (!ret) {
2730             ast_delete(block);
2731             return NULL;
2732         }
2733
2734         vec_push(block->exprs, (ast_expression*)ret);
2735
2736         return (ast_expression*)block;
2737     } else {
2738         ast_expression *left, *right;
2739         size_t diff = afterend - from;
2740         size_t middle = from + diff/2;
2741         left  = array_field_setter_node(parser, array, entity, index, value, from, middle);
2742         right = array_field_setter_node(parser, array, entity, index, value, middle, afterend);
2743         return array_accessor_split(parser, array, index, middle, left, right);
2744     }
2745 }
2746
2747 static ast_expression *array_getter_node(parser_t *parser, ast_value *array, ast_value *index, size_t from, size_t afterend)
2748 {
2749     lex_ctx ctx = ast_ctx(array);
2750
2751     if (from+1 == afterend) {
2752         ast_return      *ret;
2753         ast_array_index *subscript;
2754
2755         subscript = ast_array_index_new(ctx, (ast_expression*)array, (ast_expression*)parser_const_float(parser, from));
2756         if (!subscript)
2757             return NULL;
2758
2759         ret = ast_return_new(ctx, (ast_expression*)subscript);
2760         if (!ret) {
2761             ast_delete(subscript);
2762             return NULL;
2763         }
2764
2765         return (ast_expression*)ret;
2766     } else {
2767         ast_expression *left, *right;
2768         size_t diff = afterend - from;
2769         size_t middle = from + diff/2;
2770         left  = array_getter_node(parser, array, index, from, middle);
2771         right = array_getter_node(parser, array, index, middle, afterend);
2772         return array_accessor_split(parser, array, index, middle, left, right);
2773     }
2774 }
2775
2776 static bool parser_create_array_accessor(parser_t *parser, ast_value *array, const char *funcname, ast_value **out)
2777 {
2778     ast_function   *func = NULL;
2779     ast_value      *fval = NULL;
2780     ast_block      *body = NULL;
2781
2782     fval = ast_value_new(ast_ctx(array), funcname, TYPE_FUNCTION);
2783     if (!fval) {
2784         parseerror(parser, "failed to create accessor function value");
2785         return false;
2786     }
2787
2788     func = ast_function_new(ast_ctx(array), funcname, fval);
2789     if (!func) {
2790         ast_delete(fval);
2791         parseerror(parser, "failed to create accessor function node");
2792         return false;
2793     }
2794
2795     body = ast_block_new(ast_ctx(array));
2796     if (!body) {
2797         parseerror(parser, "failed to create block for array accessor");
2798         ast_delete(fval);
2799         ast_delete(func);
2800         return false;
2801     }
2802
2803     vec_push(func->blocks, body);
2804     *out = fval;
2805
2806     vec_push(parser->accessors, fval);
2807
2808     return true;
2809 }
2810
2811 static bool parser_create_array_setter(parser_t *parser, ast_value *array, const char *funcname)
2812 {
2813     ast_expression *root = NULL;
2814     ast_value      *index = NULL;
2815     ast_value      *value = NULL;
2816     ast_function   *func;
2817     ast_value      *fval;
2818
2819     if (!ast_istype(array->expression.next, ast_value)) {
2820         parseerror(parser, "internal error: array accessor needs to build an ast_value with a copy of the element type");
2821         return false;
2822     }
2823
2824     if (!parser_create_array_accessor(parser, array, funcname, &fval))
2825         return false;
2826     func = fval->constval.vfunc;
2827     fval->expression.next = (ast_expression*)ast_value_new(ast_ctx(array), "<void>", TYPE_VOID);
2828
2829     index = ast_value_new(ast_ctx(array), "index", TYPE_FLOAT);
2830     value = ast_value_copy((ast_value*)array->expression.next);
2831
2832     if (!index || !value) {
2833         parseerror(parser, "failed to create locals for array accessor");
2834         goto cleanup;
2835     }
2836     (void)!ast_value_set_name(value, "value"); /* not important */
2837     vec_push(fval->expression.params, index);
2838     vec_push(fval->expression.params, value);
2839
2840     root = array_setter_node(parser, array, index, value, 0, array->expression.count);
2841     if (!root) {
2842         parseerror(parser, "failed to build accessor search tree");
2843         goto cleanup;
2844     }
2845
2846     vec_push(func->blocks[0]->exprs, root);
2847     array->setter = fval;
2848     return true;
2849 cleanup:
2850     if (index) ast_delete(index);
2851     if (value) ast_delete(value);
2852     if (root)  ast_delete(root);
2853     ast_delete(func);
2854     ast_delete(fval);
2855     return false;
2856 }
2857
2858 static bool parser_create_array_field_setter(parser_t *parser, ast_value *array, const char *funcname)
2859 {
2860     ast_expression *root = NULL;
2861     ast_value      *entity = NULL;
2862     ast_value      *index = NULL;
2863     ast_value      *value = NULL;
2864     ast_function   *func;
2865     ast_value      *fval;
2866
2867     if (!ast_istype(array->expression.next, ast_value)) {
2868         parseerror(parser, "internal error: array accessor needs to build an ast_value with a copy of the element type");
2869         return false;
2870     }
2871
2872     if (!parser_create_array_accessor(parser, array, funcname, &fval))
2873         return false;
2874     func = fval->constval.vfunc;
2875     fval->expression.next = (ast_expression*)ast_value_new(ast_ctx(array), "<void>", TYPE_VOID);
2876
2877     entity = ast_value_new(ast_ctx(array), "entity", TYPE_ENTITY);
2878     index  = ast_value_new(ast_ctx(array), "index",  TYPE_FLOAT);
2879     value  = ast_value_copy((ast_value*)array->expression.next);
2880     if (!entity || !index || !value) {
2881         parseerror(parser, "failed to create locals for array accessor");
2882         goto cleanup;
2883     }
2884     (void)!ast_value_set_name(value, "value"); /* not important */
2885     vec_push(fval->expression.params, entity);
2886     vec_push(fval->expression.params, index);
2887     vec_push(fval->expression.params, value);
2888
2889     root = array_field_setter_node(parser, array, entity, index, value, 0, array->expression.count);
2890     if (!root) {
2891         parseerror(parser, "failed to build accessor search tree");
2892         goto cleanup;
2893     }
2894
2895     vec_push(func->blocks[0]->exprs, root);
2896     array->setter = fval;
2897     return true;
2898 cleanup:
2899     if (entity) ast_delete(entity);
2900     if (index)  ast_delete(index);
2901     if (value)  ast_delete(value);
2902     if (root)   ast_delete(root);
2903     ast_delete(func);
2904     ast_delete(fval);
2905     return false;
2906 }
2907
2908 static bool parser_create_array_getter(parser_t *parser, ast_value *array, const ast_expression *elemtype, const char *funcname)
2909 {
2910     ast_expression *root = NULL;
2911     ast_value      *index = NULL;
2912     ast_value      *fval;
2913     ast_function   *func;
2914
2915     /* NOTE: checking array->expression.next rather than elemtype since
2916      * for fields elemtype is a temporary fieldtype.
2917      */
2918     if (!ast_istype(array->expression.next, ast_value)) {
2919         parseerror(parser, "internal error: array accessor needs to build an ast_value with a copy of the element type");
2920         return false;
2921     }
2922
2923     if (!parser_create_array_accessor(parser, array, funcname, &fval))
2924         return false;
2925     func = fval->constval.vfunc;
2926     fval->expression.next = ast_type_copy(ast_ctx(array), elemtype);
2927
2928     index = ast_value_new(ast_ctx(array), "index", TYPE_FLOAT);
2929
2930     if (!index) {
2931         parseerror(parser, "failed to create locals for array accessor");
2932         goto cleanup;
2933     }
2934     vec_push(fval->expression.params, index);
2935
2936     root = array_getter_node(parser, array, index, 0, array->expression.count);
2937     if (!root) {
2938         parseerror(parser, "failed to build accessor search tree");
2939         goto cleanup;
2940     }
2941
2942     vec_push(func->blocks[0]->exprs, root);
2943     array->getter = fval;
2944     return true;
2945 cleanup:
2946     if (index) ast_delete(index);
2947     if (root)  ast_delete(root);
2948     ast_delete(func);
2949     ast_delete(fval);
2950     return false;
2951 }
2952
2953 static ast_value *parse_typename(parser_t *parser, ast_value **storebase);
2954 static ast_value *parse_parameter_list(parser_t *parser, ast_value *var)
2955 {
2956     lex_ctx     ctx;
2957     size_t      i;
2958     ast_value **params;
2959     ast_value  *param;
2960     ast_value  *fval;
2961     bool        first = true;
2962     bool        variadic = false;
2963
2964     ctx = parser_ctx(parser);
2965
2966     /* for the sake of less code we parse-in in this function */
2967     if (!parser_next(parser)) {
2968         parseerror(parser, "expected parameter list");
2969         return NULL;
2970     }
2971
2972     params = NULL;
2973
2974     /* parse variables until we hit a closing paren */
2975     while (parser->tok != ')') {
2976         if (!first) {
2977             /* there must be commas between them */
2978             if (parser->tok != ',') {
2979                 parseerror(parser, "expected comma or end of parameter list");
2980                 goto on_error;
2981             }
2982             if (!parser_next(parser)) {
2983                 parseerror(parser, "expected parameter");
2984                 goto on_error;
2985             }
2986         }
2987         first = false;
2988
2989         if (parser->tok == TOKEN_DOTS) {
2990             /* '...' indicates a varargs function */
2991             variadic = true;
2992             if (!parser_next(parser)) {
2993                 parseerror(parser, "expected parameter");
2994                 return NULL;
2995             }
2996             if (parser->tok != ')') {
2997                 parseerror(parser, "`...` must be the last parameter of a variadic function declaration");
2998                 goto on_error;
2999             }
3000         }
3001         else
3002         {
3003             /* for anything else just parse a typename */
3004             param = parse_typename(parser, NULL);
3005             if (!param)
3006                 goto on_error;
3007             vec_push(params, param);
3008             if (param->expression.vtype >= TYPE_VARIANT) {
3009                 char typename[1024];
3010                 ast_type_to_string((ast_expression*)param, typename, sizeof(typename));
3011                 parseerror(parser, "type not supported as part of a parameter list: %s", typename);
3012                 goto on_error;
3013             }
3014         }
3015     }
3016
3017     /* sanity check */
3018     if (vec_size(params) > 8 && opts_standard == COMPILER_QCC)
3019         (void)!parsewarning(parser, WARN_EXTENSIONS, "more than 8 parameters are not supported by this standard");
3020
3021     /* parse-out */
3022     if (!parser_next(parser)) {
3023         parseerror(parser, "parse error after typename");
3024         goto on_error;
3025     }
3026
3027     /* now turn 'var' into a function type */
3028     fval = ast_value_new(ctx, "<type()>", TYPE_FUNCTION);
3029     fval->expression.next     = (ast_expression*)var;
3030     fval->expression.variadic = variadic;
3031     var = fval;
3032
3033     var->expression.params = params;
3034     params = NULL;
3035
3036     return var;
3037
3038 on_error:
3039     ast_delete(var);
3040     for (i = 0; i < vec_size(params); ++i)
3041         ast_delete(params[i]);
3042     vec_free(params);
3043     return NULL;
3044 }
3045
3046 static ast_value *parse_arraysize(parser_t *parser, ast_value *var)
3047 {
3048     ast_expression *cexp;
3049     ast_value      *cval, *tmp;
3050     lex_ctx ctx;
3051
3052     ctx = parser_ctx(parser);
3053
3054     if (!parser_next(parser)) {
3055         ast_delete(var);
3056         parseerror(parser, "expected array-size");
3057         return NULL;
3058     }
3059
3060     cexp = parse_expression_leave(parser, true);
3061
3062     if (!cexp || !ast_istype(cexp, ast_value)) {
3063         if (cexp)
3064             ast_unref(cexp);
3065         ast_delete(var);
3066         parseerror(parser, "expected array-size as constant positive integer");
3067         return NULL;
3068     }
3069     cval = (ast_value*)cexp;
3070
3071     tmp = ast_value_new(ctx, "<type[]>", TYPE_ARRAY);
3072     tmp->expression.next = (ast_expression*)var;
3073     var = tmp;
3074
3075     if (cval->expression.vtype == TYPE_INTEGER)
3076         tmp->expression.count = cval->constval.vint;
3077     else if (cval->expression.vtype == TYPE_FLOAT)
3078         tmp->expression.count = cval->constval.vfloat;
3079     else {
3080         ast_unref(cexp);
3081         ast_delete(var);
3082         parseerror(parser, "array-size must be a positive integer constant");
3083         return NULL;
3084     }
3085     ast_unref(cexp);
3086
3087     if (parser->tok != ']') {
3088         ast_delete(var);
3089         parseerror(parser, "expected ']' after array-size");
3090         return NULL;
3091     }
3092     if (!parser_next(parser)) {
3093         ast_delete(var);
3094         parseerror(parser, "error after parsing array size");
3095         return NULL;
3096     }
3097     return var;
3098 }
3099
3100 /* Parse a complete typename.
3101  * for single-variables (ie. function parameters or typedefs) storebase should be NULL
3102  * but when parsing variables separated by comma
3103  * 'storebase' should point to where the base-type should be kept.
3104  * The base type makes up every bit of type information which comes *before* the
3105  * variable name.
3106  *
3107  * The following will be parsed in its entirety:
3108  *     void() foo()
3109  * The 'basetype' in this case is 'void()'
3110  * and if there's a comma after it, say:
3111  *     void() foo(), bar
3112  * then the type-information 'void()' can be stored in 'storebase'
3113  */
3114 static ast_value *parse_typename(parser_t *parser, ast_value **storebase)
3115 {
3116     ast_value *var, *tmp;
3117     lex_ctx    ctx;
3118
3119     const char *name = NULL;
3120     bool        isfield  = false;
3121     bool        wasarray = false;
3122
3123     ctx = parser_ctx(parser);
3124
3125     /* types may start with a dot */
3126     if (parser->tok == '.') {
3127         isfield = true;
3128         /* if we parsed a dot we need a typename now */
3129         if (!parser_next(parser)) {
3130             parseerror(parser, "expected typename for field definition");
3131             return NULL;
3132         }
3133         if (parser->tok != TOKEN_TYPENAME) {
3134             parseerror(parser, "expected typename");
3135             return NULL;
3136         }
3137     }
3138
3139     /* generate the basic type value */
3140     var = ast_value_new(ctx, "<type>", parser_token(parser)->constval.t);
3141     /* do not yet turn into a field - remember:
3142      * .void() foo; is a field too
3143      * .void()() foo; is a function
3144      */
3145
3146     /* parse on */
3147     if (!parser_next(parser)) {
3148         ast_delete(var);
3149         parseerror(parser, "parse error after typename");
3150         return NULL;
3151     }
3152
3153     /* an opening paren now starts the parameter-list of a function
3154      * this is where original-QC has parameter lists.
3155      * We allow a single parameter list here.
3156      * Much like fteqcc we don't allow `float()() x`
3157      */
3158     if (parser->tok == '(') {
3159         var = parse_parameter_list(parser, var);
3160         if (!var)
3161             return NULL;
3162     }
3163
3164     /* store the base if requested */
3165     if (storebase) {
3166         *storebase = ast_value_copy(var);
3167         if (isfield) {
3168             tmp = ast_value_new(ctx, "<type:f>", TYPE_FIELD);
3169             tmp->expression.next = (ast_expression*)*storebase;
3170             *storebase = tmp;
3171         }
3172     }
3173
3174     /* there may be a name now */
3175     if (parser->tok == TOKEN_IDENT) {
3176         name = util_strdup(parser_tokval(parser));
3177         /* parse on */
3178         if (!parser_next(parser)) {
3179             ast_delete(var);
3180             parseerror(parser, "error after variable or field declaration");
3181             return NULL;
3182         }
3183     }
3184
3185     /* now this may be an array */
3186     if (parser->tok == '[') {
3187         wasarray = true;
3188         var = parse_arraysize(parser, var);
3189         if (!var)
3190             return NULL;
3191     }
3192
3193     /* This is the point where we can turn it into a field */
3194     if (isfield) {
3195         /* turn it into a field if desired */
3196         tmp = ast_value_new(ctx, "<type:f>", TYPE_FIELD);
3197         tmp->expression.next = (ast_expression*)var;
3198         var = tmp;
3199     }
3200
3201     /* now there may be function parens again */
3202     if (parser->tok == '(' && opts_standard == COMPILER_QCC)
3203         parseerror(parser, "C-style function syntax is not allowed in -std=qcc");
3204     if (parser->tok == '(' && wasarray)
3205         parseerror(parser, "arrays as part of a return type is not supported");
3206     while (parser->tok == '(') {
3207         var = parse_parameter_list(parser, var);
3208         if (!var) {
3209             if (name)
3210                 mem_d((void*)name);
3211             ast_delete(var);
3212             return NULL;
3213         }
3214     }
3215
3216     /* finally name it */
3217     if (name) {
3218         if (!ast_value_set_name(var, name)) {
3219             ast_delete(var);
3220             parseerror(parser, "internal error: failed to set name");
3221             return NULL;
3222         }
3223         /* free the name, ast_value_set_name duplicates */
3224         mem_d((void*)name);
3225     }
3226
3227     return var;
3228 }
3229
3230 static bool parse_variable(parser_t *parser, ast_block *localblock, bool nofields, bool is_const)
3231 {
3232     ast_value *var;
3233     ast_value *proto;
3234     ast_expression *old;
3235     bool       was_end;
3236     size_t     i;
3237
3238     ast_value *basetype = NULL;
3239     bool      retval    = true;
3240     bool      isparam   = false;
3241     bool      isvector  = false;
3242     bool      cleanvar  = true;
3243     bool      wasarray  = false;
3244
3245     varentry_t varent, ve[3];
3246
3247     /* get the first complete variable */
3248     var = parse_typename(parser, &basetype);
3249     if (!var) {
3250         if (basetype)
3251             ast_delete(basetype);
3252         return false;
3253     }
3254
3255     memset(&varent, 0, sizeof(varent));
3256     memset(&ve, 0, sizeof(ve));
3257
3258     while (true) {
3259         proto = NULL;
3260         wasarray = false;
3261
3262         /* Part 0: finish the type */
3263         if (parser->tok == '(') {
3264             if (opts_standard == COMPILER_QCC)
3265                 parseerror(parser, "C-style function syntax is not allowed in -std=qcc");
3266             var = parse_parameter_list(parser, var);
3267             if (!var) {
3268                 retval = false;
3269                 goto cleanup;
3270             }
3271         }
3272         /* we only allow 1-dimensional arrays */
3273         if (parser->tok == '[') {
3274             wasarray = true;
3275             var = parse_arraysize(parser, var);
3276             if (!var) {
3277                 retval = false;
3278                 goto cleanup;
3279             }
3280         }
3281         if (parser->tok == '(' && wasarray) {
3282             parseerror(parser, "arrays as part of a return type is not supported");
3283             /* we'll still parse the type completely for now */
3284         }
3285         /* for functions returning functions */
3286         while (parser->tok == '(') {
3287             if (opts_standard == COMPILER_QCC)
3288                 parseerror(parser, "C-style function syntax is not allowed in -std=qcc");
3289             var = parse_parameter_list(parser, var);
3290             if (!var) {
3291                 retval = false;
3292                 goto cleanup;
3293             }
3294         }
3295
3296         /* Part 1:
3297          * check for validity: (end_sys_..., multiple-definitions, prototypes, ...)
3298          * Also: if there was a prototype, `var` will be deleted and set to `proto` which
3299          * is then filled with the previous definition and the parameter-names replaced.
3300          */
3301         if (!localblock) {
3302             /* Deal with end_sys_ vars */
3303             was_end = false;
3304             if (!strcmp(var->name, "end_sys_globals")) {
3305                 parser->crc_globals = vec_size(parser->globals);
3306                 was_end = true;
3307             }
3308             else if (!strcmp(var->name, "end_sys_fields")) {
3309                 parser->crc_fields = vec_size(parser->fields);
3310                 was_end = true;
3311             }
3312             if (was_end && var->expression.vtype == TYPE_FIELD) {
3313                 if (parsewarning(parser, WARN_END_SYS_FIELDS,
3314                                  "global '%s' hint should not be a field",
3315                                  parser_tokval(parser)))
3316                 {
3317                     retval = false;
3318                     goto cleanup;
3319                 }
3320             }
3321
3322             if (!nofields && var->expression.vtype == TYPE_FIELD)
3323             {
3324                 /* deal with field declarations */
3325                 old = parser_find_field(parser, var->name);
3326                 if (old) {
3327                     if (parsewarning(parser, WARN_FIELD_REDECLARED, "field `%s` already declared here: %s:%i",
3328                                      var->name, ast_ctx(old).file, (int)ast_ctx(old).line))
3329                     {
3330                         retval = false;
3331                         goto cleanup;
3332                     }
3333                     ast_delete(var);
3334                     var = NULL;
3335                     goto skipvar;
3336                     /*
3337                     parseerror(parser, "field `%s` already declared here: %s:%i",
3338                                var->name, ast_ctx(old).file, ast_ctx(old).line);
3339                     retval = false;
3340                     goto cleanup;
3341                     */
3342                 }
3343                 if (opts_standard == COMPILER_QCC &&
3344                     (old = parser_find_global(parser, var->name)))
3345                 {
3346                     parseerror(parser, "cannot declare a field and a global of the same name with -std=qcc");
3347                     parseerror(parser, "field `%s` already declared here: %s:%i",
3348                                var->name, ast_ctx(old).file, ast_ctx(old).line);
3349                     retval = false;
3350                     goto cleanup;
3351                 }
3352             }
3353             else
3354             {
3355                 /* deal with other globals */
3356                 old = parser_find_global(parser, var->name);
3357                 if (old && var->expression.vtype == TYPE_FUNCTION && old->expression.vtype == TYPE_FUNCTION)
3358                 {
3359                     /* This is a function which had a prototype */
3360                     if (!ast_istype(old, ast_value)) {
3361                         parseerror(parser, "internal error: prototype is not an ast_value");
3362                         retval = false;
3363                         goto cleanup;
3364                     }
3365                     proto = (ast_value*)old;
3366                     if (!ast_compare_type((ast_expression*)proto, (ast_expression*)var)) {
3367                         parseerror(parser, "conflicting types for `%s`, previous declaration was here: %s:%i",
3368                                    proto->name,
3369                                    ast_ctx(proto).file, ast_ctx(proto).line);
3370                         retval = false;
3371                         goto cleanup;
3372                     }
3373                     /* we need the new parameter-names */
3374                     for (i = 0; i < vec_size(proto->expression.params); ++i)
3375                         ast_value_set_name(proto->expression.params[i], var->expression.params[i]->name);
3376                     ast_delete(var);
3377                     var = proto;
3378                 }
3379                 else
3380                 {
3381                     /* other globals */
3382                     if (old) {
3383                         if (opts_standard == COMPILER_GMQCC) {
3384                             parseerror(parser, "global `%s` already declared here: %s:%i",
3385                                        var->name, ast_ctx(old).file, ast_ctx(old).line);
3386                             retval = false;
3387                             goto cleanup;
3388                         } else {
3389                             if (parsewarning(parser, WARN_DOUBLE_DECLARATION,
3390                                              "global `%s` already declared here: %s:%i",
3391                                              var->name, ast_ctx(old).file, ast_ctx(old).line))
3392                             {
3393                                 retval = false;
3394                                 goto cleanup;
3395                             }
3396                         }
3397                     }
3398                     if (opts_standard == COMPILER_QCC &&
3399                         (old = parser_find_field(parser, var->name)))
3400                     {
3401                         parseerror(parser, "cannot declare a field and a global of the same name with -std=qcc");
3402                         parseerror(parser, "global `%s` already declared here: %s:%i",
3403                                    var->name, ast_ctx(old).file, ast_ctx(old).line);
3404                         retval = false;
3405                         goto cleanup;
3406                     }
3407                 }
3408             }
3409         }
3410         else /* it's not a global */
3411         {
3412             old = parser_find_local(parser, var->name, parser->blocklocal, &isparam);
3413             if (old && !isparam) {
3414                 parseerror(parser, "local `%s` already declared here: %s:%i",
3415                            var->name, ast_ctx(old).file, (int)ast_ctx(old).line);
3416                 retval = false;
3417                 goto cleanup;
3418             }
3419             old = parser_find_local(parser, var->name, 0, &isparam);
3420             if (old && isparam) {
3421                 if (parsewarning(parser, WARN_LOCAL_SHADOWS,
3422                                  "local `%s` is shadowing a parameter", var->name))
3423                 {
3424                     parseerror(parser, "local `%s` already declared here: %s:%i",
3425                                var->name, ast_ctx(old).file, (int)ast_ctx(old).line);
3426                     retval = false;
3427                     goto cleanup;
3428                 }
3429                 if (opts_standard != COMPILER_GMQCC) {
3430                     ast_delete(var);
3431                     var = NULL;
3432                     goto skipvar;
3433                 }
3434             }
3435         }
3436
3437         if (is_const)
3438             var->isconst = true;
3439
3440         /* Part 2:
3441          * Create the global/local, and deal with vector types.
3442          */
3443         if (!proto) {
3444             if (var->expression.vtype == TYPE_VECTOR)
3445                 isvector = true;
3446             else if (var->expression.vtype == TYPE_FIELD &&
3447                      var->expression.next->expression.vtype == TYPE_VECTOR)
3448                 isvector = true;
3449
3450             if (isvector) {
3451                 if (!create_vector_members(var, ve)) {
3452                     retval = false;
3453                     goto cleanup;
3454                 }
3455             }
3456
3457             varent.name = util_strdup(var->name);
3458             varent.var  = (ast_expression*)var;
3459
3460             if (!localblock) {
3461                 /* deal with global variables, fields, functions */
3462                 if (!nofields && var->expression.vtype == TYPE_FIELD) {
3463                     vec_push(parser->fields, varent);
3464                     if (isvector) {
3465                         for (i = 0; i < 3; ++i)
3466                             vec_push(parser->fields, ve[i]);
3467                     }
3468                 }
3469                 else {
3470                     vec_push(parser->globals, varent);
3471                     if (isvector) {
3472                         for (i = 0; i < 3; ++i)
3473                             vec_push(parser->globals, ve[i]);
3474                     }
3475                 }
3476             } else {
3477                 vec_push(parser->locals, varent);
3478                 vec_push(localblock->locals, var);
3479                 if (isvector) {
3480                     for (i = 0; i < 3; ++i) {
3481                         vec_push(parser->locals, ve[i]);
3482                         ast_block_collect(localblock, ve[i].var);
3483                         ve[i].var = NULL; /* from here it's being collected in the block */
3484                     }
3485                 }
3486             }
3487
3488             varent.name = NULL;
3489             ve[0].name = ve[1].name = ve[2].name = NULL;
3490             ve[0].var  = ve[1].var  = ve[2].var  = NULL;
3491             cleanvar = false;
3492         }
3493         /* Part 2.2
3494          * deal with arrays
3495          */
3496         if (var->expression.vtype == TYPE_ARRAY) {
3497             char name[1024];
3498             snprintf(name, sizeof(name), "%s##SET", var->name);
3499             if (!parser_create_array_setter(parser, var, name))
3500                 goto cleanup;
3501             snprintf(name, sizeof(name), "%s##GET", var->name);
3502             if (!parser_create_array_getter(parser, var, var->expression.next, name))
3503                 goto cleanup;
3504         }
3505         else if (!localblock && !nofields &&
3506                  var->expression.vtype == TYPE_FIELD &&
3507                  var->expression.next->expression.vtype == TYPE_ARRAY)
3508         {
3509             char name[1024];
3510             ast_expression *telem;
3511             ast_value      *tfield;
3512             ast_value      *array = (ast_value*)var->expression.next;
3513
3514             if (!ast_istype(var->expression.next, ast_value)) {
3515                 parseerror(parser, "internal error: field element type must be an ast_value");
3516                 goto cleanup;
3517             }
3518
3519             snprintf(name, sizeof(name), "%s##SETF", var->name);
3520             if (!parser_create_array_field_setter(parser, array, name))
3521                 goto cleanup;
3522
3523             telem = ast_type_copy(ast_ctx(var), array->expression.next);
3524             tfield = ast_value_new(ast_ctx(var), "<.type>", TYPE_FIELD);
3525             tfield->expression.next = telem;
3526             snprintf(name, sizeof(name), "%s##GETFP", var->name);
3527             if (!parser_create_array_getter(parser, array, (ast_expression*)tfield, name)) {
3528                 ast_delete(tfield);
3529                 goto cleanup;
3530             }
3531             ast_delete(tfield);
3532         }
3533
3534 skipvar:
3535         if (parser->tok == ';') {
3536             ast_delete(basetype);
3537             if (!parser_next(parser)) {
3538                 parseerror(parser, "error after variable declaration");
3539                 return false;
3540             }
3541             return true;
3542         }
3543
3544         if (parser->tok == ',')
3545             goto another;
3546
3547         if (!var || (!localblock && !nofields && basetype->expression.vtype == TYPE_FIELD)) {
3548             parseerror(parser, "missing comma or semicolon while parsing variables");
3549             break;
3550         }
3551
3552         if (localblock && opts_standard == COMPILER_QCC) {
3553             if (parsewarning(parser, WARN_LOCAL_CONSTANTS,
3554                              "initializing expression turns variable `%s` into a constant in this standard",
3555                              var->name) )
3556             {
3557                 break;
3558             }
3559         }
3560
3561         if (parser->tok != '{') {
3562             if (parser->tok != '=') {
3563                 parseerror(parser, "missing semicolon or initializer");
3564                 break;
3565             }
3566
3567             if (!parser_next(parser)) {
3568                 parseerror(parser, "error parsing initializer");
3569                 break;
3570             }
3571         }
3572         else if (opts_standard == COMPILER_QCC) {
3573             parseerror(parser, "expected '=' before function body in this standard");
3574         }
3575
3576         if (parser->tok == '#') {
3577             ast_function *func;
3578
3579             if (localblock) {
3580                 parseerror(parser, "cannot declare builtins within functions");
3581                 break;
3582             }
3583             if (var->expression.vtype != TYPE_FUNCTION) {
3584                 parseerror(parser, "unexpected builtin number, '%s' is not a function", var->name);
3585                 break;
3586             }
3587             if (!parser_next(parser)) {
3588                 parseerror(parser, "expected builtin number");
3589                 break;
3590             }
3591             if (parser->tok != TOKEN_INTCONST) {
3592                 parseerror(parser, "builtin number must be an integer constant");
3593                 break;
3594             }
3595             if (parser_token(parser)->constval.i <= 0) {
3596                 parseerror(parser, "builtin number must be an integer greater than zero");
3597                 break;
3598             }
3599
3600             if (var->isconst) {
3601                 (void)!parsewarning(parser, WARN_DOUBLE_DECLARATION,
3602                                     "builtin `%s` has already been defined\n"
3603                                     " -> previous declaration here: %s:%i",
3604                                     var->name, ast_ctx(var).file, (int)ast_ctx(var).line);
3605             }
3606             else
3607             {
3608                 func = ast_function_new(ast_ctx(var), var->name, var);
3609                 if (!func) {
3610                     parseerror(parser, "failed to allocate function for `%s`", var->name);
3611                     break;
3612                 }
3613                 vec_push(parser->functions, func);
3614
3615                 func->builtin = -parser_token(parser)->constval.i;
3616             }
3617
3618             if (!parser_next(parser)) {
3619                 parseerror(parser, "expected comma or semicolon");
3620                 ast_function_delete(func);
3621                 var->constval.vfunc = NULL;
3622                 break;
3623             }
3624         }
3625         else if (parser->tok == '{' || parser->tok == '[')
3626         {
3627             if (localblock) {
3628                 parseerror(parser, "cannot declare functions within functions");
3629                 break;
3630             }
3631
3632             if (!parse_function_body(parser, var))
3633                 break;
3634             ast_delete(basetype);
3635             return true;
3636         } else {
3637             ast_expression *cexp;
3638             ast_value      *cval;
3639
3640             cexp = parse_expression_leave(parser, true);
3641             if (!cexp)
3642                 break;
3643
3644             if (!localblock) {
3645                 cval = (ast_value*)cexp;
3646                 if (!ast_istype(cval, ast_value) || !cval->isconst)
3647                     parseerror(parser, "cannot initialize a global constant variable with a non-constant expression");
3648                 else
3649                 {
3650                     var->isconst = true;
3651                     if (cval->expression.vtype == TYPE_STRING)
3652                         var->constval.vstring = parser_strdup(cval->constval.vstring);
3653                     else
3654                         memcpy(&var->constval, &cval->constval, sizeof(var->constval));
3655                     ast_unref(cval);
3656                 }
3657             } else {
3658                 shunt sy = { NULL, NULL };
3659                 vec_push(sy.out, syexp(ast_ctx(var), (ast_expression*)var));
3660                 vec_push(sy.out, syexp(ast_ctx(cexp), (ast_expression*)cexp));
3661                 vec_push(sy.ops, syop(ast_ctx(var), parser->assign_op));
3662                 if (!parser_sy_pop(parser, &sy))
3663                     ast_unref(cexp);
3664                 else {
3665                     if (vec_size(sy.out) != 1 && vec_size(sy.ops) != 0)
3666                         parseerror(parser, "internal error: leaked operands");
3667                     vec_push(localblock->exprs, (ast_expression*)sy.out[0].out);
3668                 }
3669                 vec_free(sy.out);
3670                 vec_free(sy.ops);
3671             }
3672         }
3673
3674 another:
3675         if (parser->tok == ',') {
3676             if (!parser_next(parser)) {
3677                 parseerror(parser, "expected another variable");
3678                 break;
3679             }
3680
3681             if (parser->tok != TOKEN_IDENT) {
3682                 parseerror(parser, "expected another variable");
3683                 break;
3684             }
3685             var = ast_value_copy(basetype);
3686             cleanvar = true;
3687             ast_value_set_name(var, parser_tokval(parser));
3688             if (!parser_next(parser)) {
3689                 parseerror(parser, "error parsing variable declaration");
3690                 break;
3691             }
3692             continue;
3693         }
3694
3695         if (parser->tok != ';') {
3696             parseerror(parser, "missing semicolon after variables");
3697             break;
3698         }
3699
3700         if (!parser_next(parser)) {
3701             parseerror(parser, "parse error after variable declaration");
3702             break;
3703         }
3704
3705         ast_delete(basetype);
3706         return true;
3707     }
3708
3709     if (cleanvar && var)
3710         ast_delete(var);
3711     ast_delete(basetype);
3712     return false;
3713
3714 cleanup:
3715     ast_delete(basetype);
3716     if (cleanvar && var)
3717         ast_delete(var);
3718     if (varent.name) mem_d(varent.name);
3719     if (ve[0].name)  mem_d(ve[0].name);
3720     if (ve[1].name)  mem_d(ve[1].name);
3721     if (ve[2].name)  mem_d(ve[2].name);
3722     if (ve[0].var)   mem_d(ve[0].var);
3723     if (ve[1].var)   mem_d(ve[1].var);
3724     if (ve[2].var)   mem_d(ve[2].var);
3725     return retval;
3726 }
3727
3728 static bool parser_global_statement(parser_t *parser)
3729 {
3730     if (parser->tok == TOKEN_TYPENAME || parser->tok == '.')
3731     {
3732         return parse_variable(parser, NULL, false, false);
3733     }
3734     else if (parser->tok == TOKEN_IDENT && !strcmp(parser_tokval(parser), "var"))
3735     {
3736         if (!strcmp(parser_tokval(parser), "var")) {
3737             if (!parser_next(parser)) {
3738                 parseerror(parser, "expected variable declaration after 'var'");
3739                 return false;
3740             }
3741             return parse_variable(parser, NULL, true, false);
3742         }
3743     }
3744     else if (parser->tok == TOKEN_KEYWORD)
3745     {
3746         if (!strcmp(parser_tokval(parser), "const")) {
3747             if (!parser_next(parser)) {
3748                 parseerror(parser, "expected variable declaration after 'const'");
3749                 return false;
3750             }
3751             return parse_variable(parser, NULL, true, true);
3752         }
3753         parseerror(parser, "unrecognized keyword `%s`", parser_tokval(parser));
3754         return false;
3755     }
3756     else if (parser->tok == '$')
3757     {
3758         if (!parser_next(parser)) {
3759             parseerror(parser, "parse error");
3760             return false;
3761         }
3762     }
3763     else
3764     {
3765         parseerror(parser, "unexpected token: %s", parser->lex->tok.value);
3766         return false;
3767     }
3768     return true;
3769 }
3770
3771 static uint16_t progdefs_crc_sum(uint16_t old, const char *str)
3772 {
3773     return util_crc16(old, str, strlen(str));
3774 }
3775
3776 static void progdefs_crc_file(const char *str)
3777 {
3778     /* write to progdefs.h here */
3779     (void)str;
3780 }
3781
3782 static uint16_t progdefs_crc_both(uint16_t old, const char *str)
3783 {
3784     old = progdefs_crc_sum(old, str);
3785     progdefs_crc_file(str);
3786     return old;
3787 }
3788
3789 static void generate_checksum(parser_t *parser)
3790 {
3791     uint16_t crc = 0xFFFF;
3792     size_t i;
3793
3794         crc = progdefs_crc_both(crc, "\n/* file generated by qcc, do not modify */\n\ntypedef struct\n{");
3795         crc = progdefs_crc_sum(crc, "\tint\tpad[28];\n");
3796         /*
3797         progdefs_crc_file("\tint\tpad;\n");
3798         progdefs_crc_file("\tint\tofs_return[3];\n");
3799         progdefs_crc_file("\tint\tofs_parm0[3];\n");
3800         progdefs_crc_file("\tint\tofs_parm1[3];\n");
3801         progdefs_crc_file("\tint\tofs_parm2[3];\n");
3802         progdefs_crc_file("\tint\tofs_parm3[3];\n");
3803         progdefs_crc_file("\tint\tofs_parm4[3];\n");
3804         progdefs_crc_file("\tint\tofs_parm5[3];\n");
3805         progdefs_crc_file("\tint\tofs_parm6[3];\n");
3806         progdefs_crc_file("\tint\tofs_parm7[3];\n");
3807         */
3808         for (i = 0; i < parser->crc_globals; ++i) {
3809             if (!ast_istype(parser->globals[i].var, ast_value))
3810                 continue;
3811             switch (parser->globals[i].var->expression.vtype) {
3812                 case TYPE_FLOAT:    crc = progdefs_crc_both(crc, "\tfloat\t"); break;
3813                 case TYPE_VECTOR:   crc = progdefs_crc_both(crc, "\tvec3_t\t"); break;
3814                 case TYPE_STRING:   crc = progdefs_crc_both(crc, "\tstring_t\t"); break;
3815                 case TYPE_FUNCTION: crc = progdefs_crc_both(crc, "\tfunc_t\t"); break;
3816                 default:
3817                     crc = progdefs_crc_both(crc, "\tint\t");
3818                     break;
3819             }
3820             crc = progdefs_crc_both(crc, parser->globals[i].name);
3821             crc = progdefs_crc_both(crc, ";\n");
3822         }
3823         crc = progdefs_crc_both(crc, "} globalvars_t;\n\ntypedef struct\n{\n");
3824         for (i = 0; i < parser->crc_fields; ++i) {
3825             if (!ast_istype(parser->fields[i].var, ast_value))
3826                 continue;
3827             switch (parser->fields[i].var->expression.next->expression.vtype) {
3828                 case TYPE_FLOAT:    crc = progdefs_crc_both(crc, "\tfloat\t"); break;
3829                 case TYPE_VECTOR:   crc = progdefs_crc_both(crc, "\tvec3_t\t"); break;
3830                 case TYPE_STRING:   crc = progdefs_crc_both(crc, "\tstring_t\t"); break;
3831                 case TYPE_FUNCTION: crc = progdefs_crc_both(crc, "\tfunc_t\t"); break;
3832                 default:
3833                     crc = progdefs_crc_both(crc, "\tint\t");
3834                     break;
3835             }
3836             crc = progdefs_crc_both(crc, parser->fields[i].name);
3837             crc = progdefs_crc_both(crc, ";\n");
3838         }
3839         crc = progdefs_crc_both(crc, "} entvars_t;\n\n");
3840
3841         code_crc = crc;
3842 }
3843
3844 static parser_t *parser;
3845
3846 bool parser_init()
3847 {
3848     size_t i;
3849     parser = (parser_t*)mem_a(sizeof(parser_t));
3850     if (!parser)
3851         return false;
3852
3853     memset(parser, 0, sizeof(*parser));
3854
3855     for (i = 0; i < operator_count; ++i) {
3856         if (operators[i].id == opid1('=')) {
3857             parser->assign_op = operators+i;
3858             break;
3859         }
3860     }
3861     if (!parser->assign_op) {
3862         printf("internal error: initializing parser: failed to find assign operator\n");
3863         mem_d(parser);
3864         return false;
3865     }
3866     return true;
3867 }
3868
3869 bool parser_compile()
3870 {
3871     /* initial lexer/parser state */
3872     parser->lex->flags.noops = true;
3873
3874     if (parser_next(parser))
3875     {
3876         while (parser->tok != TOKEN_EOF && parser->tok < TOKEN_ERROR)
3877         {
3878             if (!parser_global_statement(parser)) {
3879                 if (parser->tok == TOKEN_EOF)
3880                     parseerror(parser, "unexpected eof");
3881                 else if (!parser->errors)
3882                     parseerror(parser, "there have been errors, bailing out");
3883                 lex_close(parser->lex);
3884                 parser->lex = NULL;
3885                 return false;
3886             }
3887         }
3888     } else {
3889         parseerror(parser, "parse error");
3890         lex_close(parser->lex);
3891         parser->lex = NULL;
3892         return false;
3893     }
3894
3895     lex_close(parser->lex);
3896     parser->lex = NULL;
3897
3898     return !parser->errors;
3899 }
3900
3901 bool parser_compile_file(const char *filename)
3902 {
3903     parser->lex = lex_open(filename);
3904     if (!parser->lex) {
3905         con_err("failed to open file \"%s\"\n", filename);
3906         return false;
3907     }
3908     return parser_compile();
3909 }
3910
3911 bool parser_compile_string_len(const char *name, const char *str, size_t len)
3912 {
3913     parser->lex = lex_open_string(str, len, name);
3914     if (!parser->lex) {
3915         con_err("failed to create lexer for string \"%s\"\n", name);
3916         return false;
3917     }
3918     return parser_compile();
3919 }
3920
3921 bool parser_compile_string(const char *name, const char *str)
3922 {
3923     parser->lex = lex_open_string(str, strlen(str), name);
3924     if (!parser->lex) {
3925         con_err("failed to create lexer for string \"%s\"\n", name);
3926         return false;
3927     }
3928     return parser_compile();
3929 }
3930
3931 void parser_cleanup()
3932 {
3933     size_t i;
3934     for (i = 0; i < vec_size(parser->accessors); ++i) {
3935         ast_delete(parser->accessors[i]->constval.vfunc);
3936         parser->accessors[i]->constval.vfunc = NULL;
3937         ast_delete(parser->accessors[i]);
3938     }
3939     for (i = 0; i < vec_size(parser->functions); ++i) {
3940         ast_delete(parser->functions[i]);
3941     }
3942     for (i = 0; i < vec_size(parser->imm_vector); ++i) {
3943         ast_delete(parser->imm_vector[i]);
3944     }
3945     for (i = 0; i < vec_size(parser->imm_string); ++i) {
3946         ast_delete(parser->imm_string[i]);
3947     }
3948     for (i = 0; i < vec_size(parser->imm_float); ++i) {
3949         ast_delete(parser->imm_float[i]);
3950     }
3951     for (i = 0; i < vec_size(parser->fields); ++i) {
3952         ast_delete(parser->fields[i].var);
3953         mem_d(parser->fields[i].name);
3954     }
3955     for (i = 0; i < vec_size(parser->globals); ++i) {
3956         ast_delete(parser->globals[i].var);
3957         mem_d(parser->globals[i].name);
3958     }
3959     vec_free(parser->accessors);
3960     vec_free(parser->functions);
3961     vec_free(parser->imm_vector);
3962     vec_free(parser->imm_string);
3963     vec_free(parser->imm_float);
3964     vec_free(parser->globals);
3965     vec_free(parser->fields);
3966     vec_free(parser->locals);
3967
3968     mem_d(parser);
3969 }
3970
3971 bool parser_finish(const char *output)
3972 {
3973     size_t i;
3974     ir_builder *ir;
3975     bool retval = true;
3976
3977     if (!parser->errors)
3978     {
3979         ir = ir_builder_new("gmqcc_out");
3980         if (!ir) {
3981             con_out("failed to allocate builder\n");
3982             return false;
3983         }
3984
3985         for (i = 0; i < vec_size(parser->fields); ++i) {
3986             ast_value *field;
3987             bool isconst;
3988             if (!ast_istype(parser->fields[i].var, ast_value))
3989                 continue;
3990             field = (ast_value*)parser->fields[i].var;
3991             isconst = field->isconst;
3992             field->isconst = false;
3993             if (!ast_global_codegen((ast_value*)field, ir, true)) {
3994                 con_out("failed to generate field %s\n", field->name);
3995                 ir_builder_delete(ir);
3996                 return false;
3997             }
3998             if (isconst) {
3999                 ir_value *ifld;
4000                 ast_expression *subtype;
4001                 field->isconst = true;
4002                 subtype = field->expression.next;
4003                 ifld = ir_builder_create_field(ir, field->name, subtype->expression.vtype);
4004                 if (subtype->expression.vtype == TYPE_FIELD)
4005                     ifld->fieldtype = subtype->expression.next->expression.vtype;
4006                 else if (subtype->expression.vtype == TYPE_FUNCTION)
4007                     ifld->outtype = subtype->expression.next->expression.vtype;
4008                 (void)!ir_value_set_field(field->ir_v, ifld);
4009             }
4010         }
4011         for (i = 0; i < vec_size(parser->globals); ++i) {
4012             ast_value *asvalue;
4013             if (!ast_istype(parser->globals[i].var, ast_value))
4014                 continue;
4015             asvalue = (ast_value*)(parser->globals[i].var);
4016             if (!asvalue->uses && !asvalue->isconst && asvalue->expression.vtype != TYPE_FUNCTION) {
4017                 if (strcmp(asvalue->name, "end_sys_globals") &&
4018                     strcmp(asvalue->name, "end_sys_fields"))
4019                 {
4020                     retval = retval && !genwarning(ast_ctx(asvalue), WARN_UNUSED_VARIABLE,
4021                                                    "unused global: `%s`", asvalue->name);
4022                 }
4023             }
4024             if (!ast_global_codegen(asvalue, ir, false)) {
4025                 con_out("failed to generate global %s\n", parser->globals[i].name);
4026                 ir_builder_delete(ir);
4027                 return false;
4028             }
4029         }
4030         for (i = 0; i < vec_size(parser->imm_float); ++i) {
4031             if (!ast_global_codegen(parser->imm_float[i], ir, false)) {
4032                 con_out("failed to generate global %s\n", parser->imm_float[i]->name);
4033                 ir_builder_delete(ir);
4034                 return false;
4035             }
4036         }
4037         for (i = 0; i < vec_size(parser->imm_string); ++i) {
4038             if (!ast_global_codegen(parser->imm_string[i], ir, false)) {
4039                 con_out("failed to generate global %s\n", parser->imm_string[i]->name);
4040                 ir_builder_delete(ir);
4041                 return false;
4042             }
4043         }
4044         for (i = 0; i < vec_size(parser->imm_vector); ++i) {
4045             if (!ast_global_codegen(parser->imm_vector[i], ir, false)) {
4046                 con_out("failed to generate global %s\n", parser->imm_vector[i]->name);
4047                 ir_builder_delete(ir);
4048                 return false;
4049             }
4050         }
4051         for (i = 0; i < vec_size(parser->globals); ++i) {
4052             ast_value *asvalue;
4053             if (!ast_istype(parser->globals[i].var, ast_value))
4054                 continue;
4055             asvalue = (ast_value*)(parser->globals[i].var);
4056             if (asvalue->setter) {
4057                 if (!ast_global_codegen(asvalue->setter, ir, false) ||
4058                     !ast_function_codegen(asvalue->setter->constval.vfunc, ir) ||
4059                     !ir_function_finalize(asvalue->setter->constval.vfunc->ir_func))
4060                 {
4061                     printf("failed to generate setter for %s\n", parser->globals[i].name);
4062                     ir_builder_delete(ir);
4063                     return false;
4064                 }
4065             }
4066             if (asvalue->getter) {
4067                 if (!ast_global_codegen(asvalue->getter, ir, false) ||
4068                     !ast_function_codegen(asvalue->getter->constval.vfunc, ir) ||
4069                     !ir_function_finalize(asvalue->getter->constval.vfunc->ir_func))
4070                 {
4071                     printf("failed to generate getter for %s\n", parser->globals[i].name);
4072                     ir_builder_delete(ir);
4073                     return false;
4074                 }
4075             }
4076         }
4077         for (i = 0; i < vec_size(parser->fields); ++i) {
4078             ast_value *asvalue;
4079             asvalue = (ast_value*)(parser->fields[i].var->expression.next);
4080
4081             if (!ast_istype((ast_expression*)asvalue, ast_value))
4082                 continue;
4083             if (asvalue->expression.vtype != TYPE_ARRAY)
4084                 continue;
4085             if (asvalue->setter) {
4086                 if (!ast_global_codegen(asvalue->setter, ir, false) ||
4087                     !ast_function_codegen(asvalue->setter->constval.vfunc, ir) ||
4088                     !ir_function_finalize(asvalue->setter->constval.vfunc->ir_func))
4089                 {
4090                     printf("failed to generate setter for %s\n", parser->fields[i].name);
4091                     ir_builder_delete(ir);
4092                     return false;
4093                 }
4094             }
4095             if (asvalue->getter) {
4096                 if (!ast_global_codegen(asvalue->getter, ir, false) ||
4097                     !ast_function_codegen(asvalue->getter->constval.vfunc, ir) ||
4098                     !ir_function_finalize(asvalue->getter->constval.vfunc->ir_func))
4099                 {
4100                     printf("failed to generate getter for %s\n", parser->fields[i].name);
4101                     ir_builder_delete(ir);
4102                     return false;
4103                 }
4104             }
4105         }
4106         for (i = 0; i < vec_size(parser->functions); ++i) {
4107             if (!ast_function_codegen(parser->functions[i], ir)) {
4108                 con_out("failed to generate function %s\n", parser->functions[i]->name);
4109                 ir_builder_delete(ir);
4110                 return false;
4111             }
4112         }
4113         if (opts_dump)
4114             ir_builder_dump(ir, con_out);
4115         for (i = 0; i < vec_size(parser->functions); ++i) {
4116             if (!ir_function_finalize(parser->functions[i]->ir_func)) {
4117                 con_out("failed to finalize function %s\n", parser->functions[i]->name);
4118                 ir_builder_delete(ir);
4119                 return false;
4120             }
4121         }
4122
4123         if (retval) {
4124             if (opts_dumpfin)
4125                 ir_builder_dump(ir, con_out);
4126
4127             generate_checksum(parser);
4128
4129             if (!ir_builder_generate(ir, output)) {
4130                 con_out("*** failed to generate output file\n");
4131                 ir_builder_delete(ir);
4132                 return false;
4133             }
4134         }
4135
4136         ir_builder_delete(ir);
4137         return retval;
4138     }
4139
4140     con_out("*** there were compile errors\n");
4141     return false;
4142 }