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