]> de.git.xonotic.org Git - xonotic/gmqcc.git/blob - parser.c
0a8d537a2d7bb7140e03e1b580538fb934235b45
[xonotic/gmqcc.git] / parser.c
1 #include <stdio.h>
2 #include <stdarg.h>
3
4 #include "gmqcc.h"
5 #include "lexer.h"
6
7 typedef struct {
8     char *name;
9     ast_expression *var;
10 } varentry_t;
11
12 typedef struct {
13     lex_file *lex;
14     int      tok;
15
16     MEM_VECTOR_MAKE(varentry_t, globals);
17     MEM_VECTOR_MAKE(varentry_t, fields);
18     MEM_VECTOR_MAKE(ast_function*, functions);
19     MEM_VECTOR_MAKE(ast_value*, imm_float);
20     MEM_VECTOR_MAKE(ast_value*, imm_string);
21     MEM_VECTOR_MAKE(ast_value*, imm_vector);
22
23     ast_value *imm_float_zero;
24     ast_value *imm_vector_zero;
25
26     ast_function *function;
27     MEM_VECTOR_MAKE(varentry_t, locals);
28     size_t blocklocal;
29
30     size_t errors;
31
32     /* TYPE_FIELD -> parser_find_fields is used instead of find_var
33      * TODO: TYPE_VECTOR -> x, y and z are accepted in the gmqcc standard
34      * anything else: type error
35      */
36     qcint  memberof;
37 } parser_t;
38
39 MEM_VEC_FUNCTIONS(parser_t, varentry_t, globals)
40 MEM_VEC_FUNCTIONS(parser_t, varentry_t, fields)
41 MEM_VEC_FUNCTIONS(parser_t, ast_value*, imm_float)
42 MEM_VEC_FUNCTIONS(parser_t, ast_value*, imm_string)
43 MEM_VEC_FUNCTIONS(parser_t, ast_value*, imm_vector)
44 MEM_VEC_FUNCTIONS(parser_t, varentry_t, locals)
45 MEM_VEC_FUNCTIONS(parser_t, ast_function*, functions)
46
47 static void parser_pop_local(parser_t *parser);
48 static bool parser_variable(parser_t *parser, ast_block *localblock);
49 static ast_block* parser_parse_block(parser_t *parser);
50 static ast_expression* parser_parse_statement_or_block(parser_t *parser);
51 static ast_expression* parser_expression_leave(parser_t *parser, bool stopatcomma);
52 static ast_expression* parser_expression(parser_t *parser, bool stopatcomma);
53
54 void parseerror(parser_t *parser, const char *fmt, ...)
55 {
56         va_list ap;
57
58         parser->errors++;
59
60         va_start(ap, fmt);
61     vprintmsg(LVL_ERROR, parser->lex->tok->ctx.file, parser->lex->tok->ctx.line, "parse error", fmt, ap);
62         va_end(ap);
63 }
64
65 /* returns true if it counts as an error */
66 bool GMQCC_WARN parsewarning(parser_t *parser, int warntype, const char *fmt, ...)
67 {
68         va_list ap;
69         int lvl = LVL_WARNING;
70
71     if (!OPTS_WARN(warntype))
72         return false;
73
74     if (opts_werror) {
75             parser->errors++;
76             lvl = LVL_ERROR;
77         }
78
79         va_start(ap, fmt);
80     vprintmsg(lvl, parser->lex->tok->ctx.file, parser->lex->tok->ctx.line, "warning", fmt, ap);
81         va_end(ap);
82
83         return opts_werror;
84 }
85
86 /**********************************************************************
87  * some maths used for constant folding
88  */
89
90 vector vec3_add(vector a, vector b)
91 {
92     vector out;
93     out.x = a.x + b.x;
94     out.y = a.y + b.y;
95     out.z = a.z + b.z;
96     return out;
97 }
98
99 vector vec3_sub(vector a, vector b)
100 {
101     vector out;
102     out.x = a.x - b.x;
103     out.y = a.y - b.y;
104     out.z = a.z - b.z;
105     return out;
106 }
107
108 qcfloat vec3_mulvv(vector a, vector b)
109 {
110     return (a.x * b.x + a.y * b.y + a.z * b.z);
111 }
112
113 vector vec3_mulvf(vector a, float b)
114 {
115     vector out;
116     out.x = a.x * b;
117     out.y = a.y * b;
118     out.z = a.z * b;
119     return out;
120 }
121
122 /**********************************************************************
123  * parsing
124  */
125
126 bool parser_next(parser_t *parser)
127 {
128     /* lex_do kills the previous token */
129     parser->tok = lex_do(parser->lex);
130     if (parser->tok == TOKEN_EOF || parser->tok >= TOKEN_ERROR)
131         return false;
132     return true;
133 }
134
135 /* lift a token out of the parser so it's not destroyed by parser_next */
136 token *parser_lift(parser_t *parser)
137 {
138     token *tok = parser->lex->tok;
139     parser->lex->tok = NULL;
140     return tok;
141 }
142
143 #define parser_tokval(p) (p->lex->tok->value)
144 #define parser_token(p)  (p->lex->tok)
145 #define parser_ctx(p)    (p->lex->tok->ctx)
146
147 ast_value* parser_const_float(parser_t *parser, double d)
148 {
149     size_t i;
150     ast_value *out;
151     for (i = 0; i < parser->imm_float_count; ++i) {
152         if (parser->imm_float[i]->constval.vfloat == d)
153             return parser->imm_float[i];
154     }
155     out = ast_value_new(parser_ctx(parser), "#IMMEDIATE", TYPE_FLOAT);
156     out->isconst = true;
157     out->constval.vfloat = d;
158     if (!parser_t_imm_float_add(parser, out)) {
159         ast_value_delete(out);
160         return NULL;
161     }
162     return out;
163 }
164
165 ast_value* parser_const_float_0(parser_t *parser)
166 {
167     if (!parser->imm_float_zero)
168         parser->imm_float_zero = parser_const_float(parser, 0);
169     return parser->imm_float_zero;
170 }
171
172 char *parser_strdup(const char *str)
173 {
174     if (str && !*str) {
175         /* actually dup empty strings */
176         char *out = mem_a(1);
177         *out = 0;
178         return out;
179     }
180     return util_strdup(str);
181 }
182
183 ast_value* parser_const_string(parser_t *parser, const char *str)
184 {
185     size_t i;
186     ast_value *out;
187     for (i = 0; i < parser->imm_string_count; ++i) {
188         if (!strcmp(parser->imm_string[i]->constval.vstring, str))
189             return parser->imm_string[i];
190     }
191     out = ast_value_new(parser_ctx(parser), "#IMMEDIATE", TYPE_STRING);
192     out->isconst = true;
193     out->constval.vstring = parser_strdup(str);
194     if (!parser_t_imm_string_add(parser, out)) {
195         ast_value_delete(out);
196         return NULL;
197     }
198     return out;
199 }
200
201 ast_value* parser_const_vector(parser_t *parser, vector v)
202 {
203     size_t i;
204     ast_value *out;
205     for (i = 0; i < parser->imm_vector_count; ++i) {
206         if (!memcmp(&parser->imm_vector[i]->constval.vvec, &v, sizeof(v)))
207             return parser->imm_vector[i];
208     }
209     out = ast_value_new(parser_ctx(parser), "#IMMEDIATE", TYPE_VECTOR);
210     out->isconst = true;
211     out->constval.vvec = v;
212     if (!parser_t_imm_vector_add(parser, out)) {
213         ast_value_delete(out);
214         return NULL;
215     }
216     return out;
217 }
218
219 ast_value* parser_const_vector_f(parser_t *parser, float x, float y, float z)
220 {
221     vector v;
222     v.x = x;
223     v.y = y;
224     v.z = z;
225     return parser_const_vector(parser, v);
226 }
227
228 ast_value* parser_const_vector_0(parser_t *parser)
229 {
230     if (!parser->imm_vector_zero)
231         parser->imm_vector_zero = parser_const_vector_f(parser, 0, 0, 0);
232     return parser->imm_vector_zero;
233 }
234
235 ast_expression* parser_find_field(parser_t *parser, const char *name)
236 {
237     size_t i;
238     for (i = 0; i < parser->fields_count; ++i) {
239         if (!strcmp(parser->fields[i].name, name))
240             return parser->fields[i].var;
241     }
242     return NULL;
243 }
244
245 ast_expression* parser_find_global(parser_t *parser, const char *name)
246 {
247     size_t i;
248     for (i = 0; i < parser->globals_count; ++i) {
249         if (!strcmp(parser->globals[i].name, name))
250             return parser->globals[i].var;
251     }
252     return NULL;
253 }
254
255 ast_expression* parser_find_local(parser_t *parser, const char *name, size_t upto)
256 {
257     size_t i;
258     ast_value *fun;
259     for (i = parser->locals_count; i > upto;) {
260         --i;
261         if (!strcmp(parser->locals[i].name, name))
262             return parser->locals[i].var;
263     }
264     if (!parser->function)
265         return NULL;
266     fun = parser->function->vtype;
267     for (i = 0; i < fun->expression.params_count; ++i) {
268         if (!strcmp(fun->expression.params[i]->name, name))
269             return (ast_expression*)(fun->expression.params[i]);
270     }
271     return NULL;
272 }
273
274 ast_expression* parser_find_var(parser_t *parser, const char *name)
275 {
276     ast_expression *v;
277     v         = parser_find_local(parser, name, 0);
278     if (!v) v = parser_find_global(parser, name);
279     return v;
280 }
281
282 typedef struct {
283     MEM_VECTOR_MAKE(ast_value*, p);
284 } paramlist_t;
285 MEM_VEC_FUNCTIONS(paramlist_t, ast_value*, p)
286
287 static ast_value *parser_parse_type(parser_t *parser, int basetype, bool *isfunc)
288 {
289     paramlist_t params;
290     ast_value *var;
291     lex_ctx   ctx = parser_ctx(parser);
292     int vtype = basetype;
293     int temptype;
294     size_t i;
295
296     MEM_VECTOR_INIT(&params, p);
297
298     *isfunc = false;
299
300     if (parser->tok == '(') {
301         *isfunc = true;
302         while (true) {
303             ast_value *param;
304             ast_value *fld;
305             bool isfield = false;
306             bool dummy;
307
308             if (!parser_next(parser))
309                 goto on_error;
310
311             if (parser->tok == ')')
312                 break;
313
314             if (parser->tok == '.') {
315                 isfield = true;
316                 if (!parser_next(parser)) {
317                     parseerror(parser, "expected field parameter type");
318                     goto on_error;
319                 }
320             }
321
322             temptype = parser_token(parser)->constval.t;
323             if (!parser_next(parser))
324                 goto on_error;
325
326             param = parser_parse_type(parser, temptype, &dummy);
327             (void)dummy;
328
329             if (!param)
330                 goto on_error;
331
332             if (parser->tok == TOKEN_IDENT) {
333                 /* named parameter */
334                 if (!ast_value_set_name(param, parser_tokval(parser)))
335                     goto on_error;
336                 if (!parser_next(parser))
337                     goto on_error;
338             }
339
340             if (isfield) {
341                 fld = ast_value_new(ctx, param->name, TYPE_FIELD);
342                 fld->expression.next = (ast_expression*)param;
343                 param = fld;
344             }
345
346             if (!paramlist_t_p_add(&params, param)) {
347                 parseerror(parser, "Out of memory while parsing typename");
348                 goto on_error;
349             }
350
351             if (parser->tok == ',')
352                 continue;
353             if (parser->tok == ')')
354                 break;
355             parseerror(parser, "Unexpected token");
356             goto on_error;
357         }
358         if (!parser_next(parser))
359             goto on_error;
360     }
361
362     var = ast_value_new(ctx, "<unnamed>", vtype);
363     if (!var)
364         goto on_error;
365     MEM_VECTOR_MOVE(&params, p, &var->expression, params);
366     return var;
367 on_error:
368     for (i = 0; i < params.p_count; ++i)
369         ast_value_delete(params.p[i]);
370     MEM_VECTOR_CLEAR(&params, p);
371     return NULL;
372 }
373
374 typedef struct
375 {
376     size_t etype; /* 0 = expression, others are operators */
377     int             paren;
378     size_t          off;
379     ast_expression *out;
380     ast_block      *block; /* for commas and function calls */
381     lex_ctx ctx;
382 } sy_elem;
383 typedef struct
384 {
385     MEM_VECTOR_MAKE(sy_elem, out);
386     MEM_VECTOR_MAKE(sy_elem, ops);
387 } shunt;
388 MEM_VEC_FUNCTIONS(shunt, sy_elem, out)
389 MEM_VEC_FUNCTIONS(shunt, sy_elem, ops)
390
391 static sy_elem syexp(lex_ctx ctx, ast_expression *v) {
392     sy_elem e;
393     e.etype = 0;
394     e.out   = v;
395     e.block = NULL;
396     e.ctx   = ctx;
397     e.paren = 0;
398     return e;
399 }
400
401 static sy_elem syblock(lex_ctx ctx, ast_block *v) {
402     sy_elem e;
403     e.etype = 0;
404     e.out   = (ast_expression*)v;
405     e.block = v;
406     e.ctx   = ctx;
407     e.paren = 0;
408     return e;
409 }
410
411 static sy_elem syop(lex_ctx ctx, const oper_info *op) {
412     sy_elem e;
413     e.etype = 1 + (op - operators);
414     e.out   = NULL;
415     e.block = NULL;
416     e.ctx   = ctx;
417     e.paren = 0;
418     return e;
419 }
420
421 static sy_elem syparen(lex_ctx ctx, int p, size_t off) {
422     sy_elem e;
423     e.etype = 0;
424     e.off   = off;
425     e.out   = NULL;
426     e.block = NULL;
427     e.ctx   = ctx;
428     e.paren = p;
429     return e;
430 }
431
432 #ifdef DEBUGSHUNT
433 # define DEBUGSHUNTDO(x) x
434 #else
435 # define DEBUGSHUNTDO(x)
436 #endif
437
438 static bool parser_sy_pop(parser_t *parser, shunt *sy)
439 {
440     const oper_info *op;
441     lex_ctx ctx;
442     ast_expression *out = NULL;
443     ast_expression *exprs[3];
444     ast_block      *blocks[3];
445     ast_value      *asvalue[3];
446     size_t i, assignop;
447     qcint  generated_op = 0;
448
449     if (!sy->ops_count) {
450         parseerror(parser, "internal error: missing operator");
451         return false;
452     }
453
454     if (sy->ops[sy->ops_count-1].paren) {
455         parseerror(parser, "unmatched parenthesis");
456         return false;
457     }
458
459     op = &operators[sy->ops[sy->ops_count-1].etype - 1];
460     ctx = sy->ops[sy->ops_count-1].ctx;
461
462     DEBUGSHUNTDO(printf("apply %s\n", op->op));
463
464     if (sy->out_count < op->operands) {
465         parseerror(parser, "internal error: not enough operands: %i (operator %s (%i))", sy->out_count,
466                    op->op, (int)op->id);
467         return false;
468     }
469
470     sy->ops_count--;
471
472     sy->out_count -= op->operands;
473     for (i = 0; i < op->operands; ++i) {
474         exprs[i]  = sy->out[sy->out_count+i].out;
475         blocks[i] = sy->out[sy->out_count+i].block;
476         asvalue[i] = (ast_value*)exprs[i];
477     }
478
479     if (blocks[0] && !blocks[0]->exprs_count && op->id != opid1(',')) {
480         parseerror(parser, "internal error: operator cannot be applied on empty blocks");
481         return false;
482     }
483
484 #define NotSameType(T) \
485              (exprs[0]->expression.vtype != exprs[1]->expression.vtype || \
486               exprs[0]->expression.vtype != T)
487 #define CanConstFold1(A) \
488              (ast_istype((A), ast_value) && ((ast_value*)(A))->isconst)
489 #define CanConstFold(A, B) \
490              (CanConstFold1(A) && CanConstFold1(B))
491 #define ConstV(i) (asvalue[(i)]->constval.vvec)
492 #define ConstF(i) (asvalue[(i)]->constval.vfloat)
493 #define ConstS(i) (asvalue[(i)]->constval.vstring)
494     switch (op->id)
495     {
496         default:
497             parseerror(parser, "internal error: unhandled operator: %s (%i)", op->op, (int)op->id);
498             return false;
499
500         case opid1('.'):
501             if (exprs[0]->expression.vtype == TYPE_ENTITY) {
502                 if (exprs[1]->expression.vtype != TYPE_FIELD) {
503                     parseerror(parser, "type error: right hand of member-operand should be an entity-field");
504                     return false;
505                 }
506                 out = (ast_expression*)ast_entfield_new(ctx, exprs[0], exprs[1]);
507             }
508             else if (exprs[0]->expression.vtype == TYPE_VECTOR) {
509                 parseerror(parser, "internal error: vector access is not supposed to be handled at this point");
510                 return false;
511             }
512             else {
513                 parseerror(parser, "type error: member-of operator on something that is not an entity or vector");
514                 return false;
515             }
516             break;
517
518         case opid1(','):
519             if (blocks[0]) {
520                 if (!ast_block_exprs_add(blocks[0], exprs[1]))
521                     return false;
522             } else {
523                 blocks[0] = ast_block_new(ctx);
524                 if (!ast_block_exprs_add(blocks[0], exprs[0]) ||
525                     !ast_block_exprs_add(blocks[0], exprs[1]))
526                 {
527                     return false;
528                 }
529             }
530             if (!ast_block_set_type(blocks[0], exprs[1]))
531                 return false;
532
533             sy->out[sy->out_count++] = syblock(ctx, blocks[0]);
534             return true;
535
536         case opid2('-','P'):
537             switch (exprs[0]->expression.vtype) {
538                 case TYPE_FLOAT:
539                     if (CanConstFold1(exprs[0]))
540                         out = (ast_expression*)parser_const_float(parser, -ConstF(0));
541                     else
542                         out = (ast_expression*)ast_binary_new(ctx, INSTR_SUB_F,
543                                                               (ast_expression*)parser_const_float_0(parser),
544                                                               exprs[0]);
545                     break;
546                 case TYPE_VECTOR:
547                     if (CanConstFold1(exprs[0]))
548                         out = (ast_expression*)parser_const_vector_f(parser,
549                             -ConstV(0).x, -ConstV(0).y, -ConstV(0).z);
550                     else
551                         out = (ast_expression*)ast_binary_new(ctx, INSTR_SUB_V,
552                                                               (ast_expression*)parser_const_vector_0(parser),
553                                                               exprs[0]);
554                     break;
555                 default:
556                 parseerror(parser, "invalid types used in expression: cannot negate type %s",
557                            type_name[exprs[0]->expression.vtype]);
558                 return false;
559             }
560             break;
561
562         case opid2('!','P'):
563             switch (exprs[0]->expression.vtype) {
564                 case TYPE_FLOAT:
565                     if (CanConstFold1(exprs[0]))
566                         out = (ast_expression*)parser_const_float(parser, !ConstF(0));
567                     else
568                         out = (ast_expression*)ast_unary_new(ctx, INSTR_NOT_F, exprs[0]);
569                     break;
570                 case TYPE_VECTOR:
571                     if (CanConstFold1(exprs[0]))
572                         out = (ast_expression*)parser_const_float(parser,
573                             (!ConstV(0).x && !ConstV(0).y && !ConstV(0).z));
574                     else
575                         out = (ast_expression*)ast_unary_new(ctx, INSTR_NOT_V, exprs[0]);
576                     break;
577                 case TYPE_STRING:
578                     if (CanConstFold1(exprs[0]))
579                         out = (ast_expression*)parser_const_float(parser, !ConstS(0) || !*ConstS(0));
580                     else
581                         out = (ast_expression*)ast_unary_new(ctx, INSTR_NOT_S, exprs[0]);
582                     break;
583                 /* we don't constant-fold NOT for these types */
584                 case TYPE_ENTITY:
585                     out = (ast_expression*)ast_unary_new(ctx, INSTR_NOT_ENT, exprs[0]);
586                     break;
587                 case TYPE_FUNCTION:
588                     out = (ast_expression*)ast_unary_new(ctx, INSTR_NOT_FNC, exprs[0]);
589                     break;
590                 default:
591                 parseerror(parser, "invalid types used in expression: cannot logically negate type %s",
592                            type_name[exprs[0]->expression.vtype]);
593                 return false;
594             }
595             break;
596
597         case opid1('+'):
598             if (exprs[0]->expression.vtype != exprs[1]->expression.vtype ||
599                 (exprs[0]->expression.vtype != TYPE_VECTOR && exprs[0]->expression.vtype != TYPE_FLOAT) )
600             {
601                 parseerror(parser, "invalid types used in expression: cannot add type %s and %s",
602                            type_name[exprs[0]->expression.vtype],
603                            type_name[exprs[1]->expression.vtype]);
604                 return false;
605             }
606             switch (exprs[0]->expression.vtype) {
607                 case TYPE_FLOAT:
608                     if (CanConstFold(exprs[0], exprs[1]))
609                     {
610                         out = (ast_expression*)parser_const_float(parser, ConstF(0) + ConstF(1));
611                     }
612                     else
613                         out = (ast_expression*)ast_binary_new(ctx, INSTR_ADD_F, exprs[0], exprs[1]);
614                     break;
615                 case TYPE_VECTOR:
616                     if (CanConstFold(exprs[0], exprs[1]))
617                         out = (ast_expression*)parser_const_vector(parser, vec3_add(ConstV(0), ConstV(1)));
618                     else
619                         out = (ast_expression*)ast_binary_new(ctx, INSTR_ADD_V, exprs[0], exprs[1]);
620                     break;
621                 default:
622                     parseerror(parser, "invalid types used in expression: cannot add type %s and %s",
623                                type_name[exprs[0]->expression.vtype],
624                                type_name[exprs[1]->expression.vtype]);
625                     return false;
626             };
627             break;
628         case opid1('-'):
629             if (exprs[0]->expression.vtype != exprs[1]->expression.vtype ||
630                 (exprs[0]->expression.vtype != TYPE_VECTOR && exprs[0]->expression.vtype != TYPE_FLOAT) )
631             {
632                 parseerror(parser, "invalid types used in expression: cannot subtract type %s from %s",
633                            type_name[exprs[1]->expression.vtype],
634                            type_name[exprs[0]->expression.vtype]);
635                 return false;
636             }
637             switch (exprs[0]->expression.vtype) {
638                 case TYPE_FLOAT:
639                     if (CanConstFold(exprs[0], exprs[1]))
640                         out = (ast_expression*)parser_const_float(parser, ConstF(0) - ConstF(1));
641                     else
642                         out = (ast_expression*)ast_binary_new(ctx, INSTR_SUB_F, exprs[0], exprs[1]);
643                     break;
644                 case TYPE_VECTOR:
645                     if (CanConstFold(exprs[0], exprs[1]))
646                         out = (ast_expression*)parser_const_vector(parser, vec3_sub(ConstV(0), ConstV(1)));
647                     else
648                         out = (ast_expression*)ast_binary_new(ctx, INSTR_SUB_V, exprs[0], exprs[1]);
649                     break;
650                 default:
651                     parseerror(parser, "invalid types used in expression: cannot subtract type %s from %s",
652                                type_name[exprs[1]->expression.vtype],
653                                type_name[exprs[0]->expression.vtype]);
654                     return false;
655             };
656             break;
657         case opid1('*'):
658             if (exprs[0]->expression.vtype != exprs[1]->expression.vtype &&
659                 exprs[0]->expression.vtype != TYPE_VECTOR &&
660                 exprs[0]->expression.vtype != TYPE_FLOAT &&
661                 exprs[1]->expression.vtype != TYPE_VECTOR &&
662                 exprs[1]->expression.vtype != TYPE_FLOAT)
663             {
664                 parseerror(parser, "invalid types used in expression: cannot multiply types %s and %s",
665                            type_name[exprs[1]->expression.vtype],
666                            type_name[exprs[0]->expression.vtype]);
667                 return false;
668             }
669             switch (exprs[0]->expression.vtype) {
670                 case TYPE_FLOAT:
671                     if (exprs[1]->expression.vtype == TYPE_VECTOR)
672                     {
673                         if (CanConstFold(exprs[0], exprs[1]))
674                             out = (ast_expression*)parser_const_vector(parser, vec3_mulvf(ConstV(1), ConstF(0)));
675                         else
676                             out = (ast_expression*)ast_binary_new(ctx, INSTR_MUL_FV, exprs[0], exprs[1]);
677                     }
678                     else
679                     {
680                         if (CanConstFold(exprs[0], exprs[1]))
681                             out = (ast_expression*)parser_const_float(parser, ConstF(0) * ConstF(1));
682                         else
683                             out = (ast_expression*)ast_binary_new(ctx, INSTR_MUL_F, exprs[0], exprs[1]);
684                     }
685                     break;
686                 case TYPE_VECTOR:
687                     if (exprs[1]->expression.vtype == TYPE_FLOAT)
688                     {
689                         if (CanConstFold(exprs[0], exprs[1]))
690                             out = (ast_expression*)parser_const_vector(parser, vec3_mulvf(ConstV(0), ConstF(1)));
691                         else
692                             out = (ast_expression*)ast_binary_new(ctx, INSTR_MUL_VF, exprs[0], exprs[1]);
693                     }
694                     else
695                     {
696                         if (CanConstFold(exprs[0], exprs[1]))
697                             out = (ast_expression*)parser_const_float(parser, vec3_mulvv(ConstV(0), ConstV(1)));
698                         else
699                             out = (ast_expression*)ast_binary_new(ctx, INSTR_MUL_V, exprs[0], exprs[1]);
700                     }
701                     break;
702                 default:
703                     parseerror(parser, "invalid types used in expression: cannot multiply types %s and %s",
704                                type_name[exprs[1]->expression.vtype],
705                                type_name[exprs[0]->expression.vtype]);
706                     return false;
707             };
708             break;
709         case opid1('/'):
710             if (NotSameType(TYPE_FLOAT)) {
711                 parseerror(parser, "invalid types used in expression: cannot divide types %s and %s",
712                            type_name[exprs[0]->expression.vtype],
713                            type_name[exprs[1]->expression.vtype]);
714                 return false;
715             }
716             if (CanConstFold(exprs[0], exprs[1]))
717                 out = (ast_expression*)parser_const_float(parser, ConstF(0) / ConstF(1));
718             else
719                 out = (ast_expression*)ast_binary_new(ctx, INSTR_DIV_F, exprs[0], exprs[1]);
720             break;
721         case opid1('%'):
722         case opid2('%','='):
723             parseerror(parser, "qc does not have a modulo operator");
724             return false;
725         case opid1('|'):
726         case opid1('&'):
727             if (NotSameType(TYPE_FLOAT)) {
728                 parseerror(parser, "invalid types used in expression: cannot perform bit operations between types %s and %s",
729                            type_name[exprs[0]->expression.vtype],
730                            type_name[exprs[1]->expression.vtype]);
731                 return false;
732             }
733             if (CanConstFold(exprs[0], exprs[1]))
734                 out = (ast_expression*)parser_const_float(parser,
735                     (op->id == opid1('|') ? (float)( ((qcint)ConstF(0)) | ((qcint)ConstF(1)) ) :
736                                             (float)( ((qcint)ConstF(0)) & ((qcint)ConstF(1)) ) ));
737             else
738                 out = (ast_expression*)ast_binary_new(ctx,
739                     (op->id == opid1('|') ? INSTR_BITOR : INSTR_BITAND),
740                     exprs[0], exprs[1]);
741             break;
742         case opid1('^'):
743             parseerror(parser, "TODO: bitxor");
744             return false;
745
746         case opid2('<','<'):
747         case opid2('>','>'):
748         case opid3('<','<','='):
749         case opid3('>','>','='):
750             parseerror(parser, "TODO: shifts");
751             return false;
752
753         case opid2('|','|'):
754             generated_op += 1; /* INSTR_OR */
755         case opid2('&','&'):
756             generated_op += INSTR_AND;
757             if (NotSameType(TYPE_FLOAT)) {
758                 parseerror(parser, "invalid types used in expression: cannot perform logical operations between types %s and %s",
759                            type_name[exprs[0]->expression.vtype],
760                            type_name[exprs[1]->expression.vtype]);
761                 parseerror(parser, "TODO: logical ops for arbitrary types using INSTR_NOT");
762                 parseerror(parser, "TODO: optional early out");
763                 return false;
764             }
765             if (opts_standard == COMPILER_GMQCC)
766                 printf("TODO: early out logic\n");
767             if (CanConstFold(exprs[0], exprs[1]))
768                 out = (ast_expression*)parser_const_float(parser,
769                     (generated_op == INSTR_OR ? (ConstF(0) || ConstF(1)) : (ConstF(0) && ConstF(1))));
770             else
771                 out = (ast_expression*)ast_binary_new(ctx, generated_op, exprs[0], exprs[1]);
772             break;
773
774         case opid1('>'):
775             generated_op += 1; /* INSTR_GT */
776         case opid1('<'):
777             generated_op += 1; /* INSTR_LT */
778         case opid2('>', '='):
779             generated_op += 1; /* INSTR_GE */
780         case opid2('<', '='):
781             generated_op += INSTR_LE;
782             if (NotSameType(TYPE_FLOAT)) {
783                 parseerror(parser, "invalid types used in expression: cannot perform comparison between types %s and %s",
784                            type_name[exprs[0]->expression.vtype],
785                            type_name[exprs[1]->expression.vtype]);
786                 return false;
787             }
788             out = (ast_expression*)ast_binary_new(ctx, generated_op, exprs[0], exprs[1]);
789             break;
790         case opid2('!', '='):
791             if (exprs[0]->expression.vtype != exprs[1]->expression.vtype) {
792                 parseerror(parser, "invalid types used in expression: cannot perform comparison between types %s and %s",
793                            type_name[exprs[0]->expression.vtype],
794                            type_name[exprs[1]->expression.vtype]);
795                 return false;
796             }
797             out = (ast_expression*)ast_binary_new(ctx, type_ne_instr[exprs[0]->expression.vtype], exprs[0], exprs[1]);
798             break;
799         case opid2('=', '='):
800             if (exprs[0]->expression.vtype != exprs[1]->expression.vtype) {
801                 parseerror(parser, "invalid types used in expression: cannot perform comparison between types %s and %s",
802                            type_name[exprs[0]->expression.vtype],
803                            type_name[exprs[1]->expression.vtype]);
804                 return false;
805             }
806             out = (ast_expression*)ast_binary_new(ctx, type_eq_instr[exprs[0]->expression.vtype], exprs[0], exprs[1]);
807             break;
808
809         case opid1('='):
810             if (ast_istype(exprs[0], ast_entfield))
811                 assignop = type_storep_instr[exprs[0]->expression.vtype];
812             else
813                 assignop = type_store_instr[exprs[0]->expression.vtype];
814             out = (ast_expression*)ast_store_new(ctx, assignop, exprs[0], exprs[1]);
815             break;
816         case opid2('+','='):
817         case opid2('-','='):
818             if (exprs[0]->expression.vtype != exprs[1]->expression.vtype ||
819                 (exprs[0]->expression.vtype != TYPE_VECTOR && exprs[0]->expression.vtype != TYPE_FLOAT) )
820             {
821                 parseerror(parser, "invalid types used in expression: cannot add or subtract type %s and %s",
822                            type_name[exprs[0]->expression.vtype],
823                            type_name[exprs[1]->expression.vtype]);
824                 return false;
825             }
826             if (ast_istype(exprs[0], ast_entfield))
827                 assignop = type_storep_instr[exprs[0]->expression.vtype];
828             else
829                 assignop = type_store_instr[exprs[0]->expression.vtype];
830             switch (exprs[0]->expression.vtype) {
831                 case TYPE_FLOAT:
832                     out = (ast_expression*)ast_binstore_new(ctx, assignop,
833                                                             (op->id == opid2('+','=') ? INSTR_ADD_F : INSTR_SUB_F),
834                                                             exprs[0], exprs[1]);
835                     break;
836                 case TYPE_VECTOR:
837                     out = (ast_expression*)ast_binstore_new(ctx, assignop,
838                                                             (op->id == opid2('+','=') ? INSTR_ADD_V : INSTR_SUB_V),
839                                                             exprs[0], exprs[1]);
840                     break;
841                 default:
842                     parseerror(parser, "invalid types used in expression: cannot add or subtract type %s and %s",
843                                type_name[exprs[0]->expression.vtype],
844                                type_name[exprs[1]->expression.vtype]);
845                     return false;
846             };
847             break;
848     }
849 #undef NotSameType
850
851     if (!out) {
852         parseerror(parser, "failed to apply operand %s", op->op);
853         return false;
854     }
855
856     DEBUGSHUNTDO(printf("applied %s\n", op->op));
857     sy->out[sy->out_count++] = syexp(ctx, out);
858     return true;
859 }
860
861 static bool parser_close_call(parser_t *parser, shunt *sy)
862 {
863     /* was a function call */
864     ast_expression *fun;
865     ast_call       *call;
866
867     size_t          fid;
868     size_t          paramcount;
869
870     sy->ops_count--;
871     fid = sy->ops[sy->ops_count].off;
872
873     /* out[fid] is the function
874      * everything above is parameters...
875      * 0 params = nothing
876      * 1 params = ast_expression
877      * more = ast_block
878      */
879
880     if (sy->out_count < 1 || sy->out_count <= fid) {
881         parseerror(parser, "internal error: function call needs function and parameter list...");
882         return false;
883     }
884
885     fun = sy->out[fid].out;
886
887     call = ast_call_new(sy->ops[sy->ops_count].ctx, fun);
888     if (!call) {
889         parseerror(parser, "out of memory");
890         return false;
891     }
892
893     if (fid+1 == sy->out_count) {
894         /* no arguments */
895         paramcount = 0;
896     } else if (fid+2 == sy->out_count) {
897         ast_block *params;
898         sy->out_count--;
899         params = sy->out[sy->out_count].block;
900         if (!params) {
901             /* 1 param */
902             paramcount = 1;
903             if (!ast_call_params_add(call, sy->out[sy->out_count].out)) {
904                 ast_delete(sy->out[sy->out_count].out);
905                 parseerror(parser, "out of memory");
906                 return false;
907             }
908         } else {
909             paramcount = params->exprs_count;
910             MEM_VECTOR_MOVE(params, exprs, call, params);
911             ast_delete(params);
912         }
913     } else {
914         parseerror(parser, "invalid function call");
915         return false;
916     }
917
918     /* overwrite fid, the function, with a call */
919     sy->out[fid] = syexp(call->expression.node.context, (ast_expression*)call);
920
921     if (fun->expression.vtype != TYPE_FUNCTION) {
922         parseerror(parser, "not a function (%s)", type_name[fun->expression.vtype]);
923         return false;
924     }
925
926     if (!fun->expression.next) {
927         parseerror(parser, "could not determine function return type");
928         return false;
929     } else {
930         if (fun->expression.params_count != paramcount) {
931             ast_value *fval;
932             fval = (ast_istype(fun, ast_value) ? ((ast_value*)fun) : NULL);
933             if (opts_standard == COMPILER_GMQCC)
934             {
935                 if (fval)
936                     parseerror(parser, "too few parameters for call to %s: expected %i, got %i",
937                                fval->name, (int)fun->expression.params_count, paramcount);
938                 else
939                     parseerror(parser, "too few parameters for function call: expected %i, got %i",
940                                (int)fun->expression.params_count, paramcount);
941                 return false;
942             }
943             else
944             {
945                 if (fval)
946                     return !parsewarning(parser, WARN_TOO_FEW_PARAMETERS,
947                                          "too few parameters for call to %s: expected %i, got %i",
948                                          fval->name, (int)fun->expression.params_count, paramcount);
949                 else
950                     return !parsewarning(parser, WARN_TOO_FEW_PARAMETERS,
951                                          "too few parameters for function call: expected %i, got %i",
952                                          (int)fun->expression.params_count, paramcount);
953             }
954         }
955     }
956
957     return true;
958 }
959
960 static bool parser_close_paren(parser_t *parser, shunt *sy, bool functions_only)
961 {
962     if (!sy->ops_count) {
963         parseerror(parser, "unmatched closing paren");
964         return false;
965     }
966     if (sy->ops[sy->ops_count-1].paren == 1) {
967         parseerror(parser, "empty parenthesis expression");
968         return false;
969     }
970     while (sy->ops_count) {
971         if (sy->ops[sy->ops_count-1].paren == 'f') {
972             if (!parser_close_call(parser, sy))
973                 return false;
974             break;
975         }
976         if (sy->ops[sy->ops_count-1].paren == 1) {
977             sy->ops_count--;
978             return !functions_only;
979         }
980         if (!parser_sy_pop(parser, sy))
981             return false;
982     }
983     return true;
984 }
985
986 static void parser_reclassify_token(parser_t *parser)
987 {
988     size_t i;
989     for (i = 0; i < operator_count; ++i) {
990         if (!strcmp(parser_tokval(parser), operators[i].op)) {
991             parser->tok = TOKEN_OPERATOR;
992             return;
993         }
994     }
995 }
996
997 static ast_expression* parser_expression_leave(parser_t *parser, bool stopatcomma)
998 {
999     ast_expression *expr = NULL;
1000     shunt sy;
1001     bool wantop = false;
1002     bool gotmemberof = false;
1003
1004     /* count the parens because an if starts with one, so the
1005      * end of a condition is an unmatched closing paren
1006      */
1007     int parens = 0;
1008
1009     MEM_VECTOR_INIT(&sy, out);
1010     MEM_VECTOR_INIT(&sy, ops);
1011
1012     parser->lex->flags.noops = false;
1013
1014     parser_reclassify_token(parser);
1015
1016     while (true)
1017     {
1018         if (gotmemberof)
1019             gotmemberof = false;
1020         else
1021             parser->memberof = 0;
1022
1023         if (parser->tok == TOKEN_IDENT)
1024         {
1025             ast_expression *var;
1026             if (wantop) {
1027                 parseerror(parser, "expected operator or end of statement");
1028                 goto onerr;
1029             }
1030             wantop = true;
1031             /* variable */
1032             if (opts_standard == COMPILER_GMQCC)
1033             {
1034                 if (parser->memberof == TYPE_ENTITY) {
1035                     /* still get vars first since there could be a fieldpointer */
1036                     var = parser_find_var(parser, parser_tokval(parser));
1037                     if (!var)
1038                         var = parser_find_field(parser, parser_tokval(parser));
1039                 }
1040                 else if (parser->memberof == TYPE_VECTOR)
1041                 {
1042                     parseerror(parser, "TODO: implement effective vector member access");
1043                     goto onerr;
1044                 }
1045                 else if (parser->memberof) {
1046                     parseerror(parser, "namespace for member not found");
1047                     goto onerr;
1048                 }
1049                 else
1050                     var = parser_find_var(parser, parser_tokval(parser));
1051             } else {
1052                 var = parser_find_var(parser, parser_tokval(parser));
1053                 if (!var)
1054                     var = parser_find_field(parser, parser_tokval(parser));
1055             }
1056             if (!var) {
1057                 parseerror(parser, "unexpected ident: %s", parser_tokval(parser));
1058                 goto onerr;
1059             }
1060             if (!shunt_out_add(&sy, syexp(parser_ctx(parser), var))) {
1061                 parseerror(parser, "out of memory");
1062                 goto onerr;
1063             }
1064             DEBUGSHUNTDO(printf("push %s\n", parser_tokval(parser)));
1065         }
1066         else if (parser->tok == TOKEN_FLOATCONST) {
1067             ast_value *val;
1068             if (wantop) {
1069                 parseerror(parser, "expected operator or end of statement, got constant");
1070                 goto onerr;
1071             }
1072             wantop = true;
1073             val = parser_const_float(parser, (parser_token(parser)->constval.f));
1074             if (!val)
1075                 return false;
1076             if (!shunt_out_add(&sy, syexp(parser_ctx(parser), (ast_expression*)val))) {
1077                 parseerror(parser, "out of memory");
1078                 goto onerr;
1079             }
1080             DEBUGSHUNTDO(printf("push %g\n", parser_token(parser)->constval.f));
1081         }
1082         else if (parser->tok == TOKEN_INTCONST) {
1083             ast_value *val;
1084             if (wantop) {
1085                 parseerror(parser, "expected operator or end of statement, got constant");
1086                 goto onerr;
1087             }
1088             wantop = true;
1089             val = parser_const_float(parser, (double)(parser_token(parser)->constval.i));
1090             if (!val)
1091                 return false;
1092             if (!shunt_out_add(&sy, syexp(parser_ctx(parser), (ast_expression*)val))) {
1093                 parseerror(parser, "out of memory");
1094                 goto onerr;
1095             }
1096             DEBUGSHUNTDO(printf("push %i\n", parser_token(parser)->constval.i));
1097         }
1098         else if (parser->tok == TOKEN_STRINGCONST) {
1099             ast_value *val;
1100             if (wantop) {
1101                 parseerror(parser, "expected operator or end of statement, got constant");
1102                 goto onerr;
1103             }
1104             wantop = true;
1105             val = parser_const_string(parser, parser_tokval(parser));
1106             if (!val)
1107                 return false;
1108             if (!shunt_out_add(&sy, syexp(parser_ctx(parser), (ast_expression*)val))) {
1109                 parseerror(parser, "out of memory");
1110                 goto onerr;
1111             }
1112             DEBUGSHUNTDO(printf("push string\n"));
1113         }
1114         else if (parser->tok == TOKEN_VECTORCONST) {
1115             ast_value *val;
1116             if (wantop) {
1117                 parseerror(parser, "expected operator or end of statement, got constant");
1118                 goto onerr;
1119             }
1120             wantop = true;
1121             val = parser_const_vector(parser, parser_token(parser)->constval.v);
1122             if (!val)
1123                 return false;
1124             if (!shunt_out_add(&sy, syexp(parser_ctx(parser), (ast_expression*)val))) {
1125                 parseerror(parser, "out of memory");
1126                 goto onerr;
1127             }
1128             DEBUGSHUNTDO(printf("push '%g %g %g'\n",
1129                                 parser_token(parser)->constval.v.x,
1130                                 parser_token(parser)->constval.v.y,
1131                                 parser_token(parser)->constval.v.z));
1132         }
1133         else if (parser->tok == '(') {
1134             parseerror(parser, "internal error: '(' should be classified as operator");
1135             goto onerr;
1136         }
1137         else if (parser->tok == ')') {
1138             if (wantop) {
1139                 DEBUGSHUNTDO(printf("do[op] )\n"));
1140                 --parens;
1141                 if (parens < 0)
1142                     break;
1143                 /* we do expect an operator next */
1144                 /* closing an opening paren */
1145                 if (!parser_close_paren(parser, &sy, false))
1146                     goto onerr;
1147             } else {
1148                 DEBUGSHUNTDO(printf("do[nop] )\n"));
1149                 --parens;
1150                 if (parens < 0)
1151                     break;
1152                 /* allowed for function calls */
1153                 if (!parser_close_paren(parser, &sy, true))
1154                     goto onerr;
1155             }
1156             wantop = true;
1157         }
1158         else if (parser->tok != TOKEN_OPERATOR) {
1159             if (wantop) {
1160                 parseerror(parser, "expected operator or end of statement");
1161                 goto onerr;
1162             }
1163             break;
1164         }
1165         else
1166         {
1167             /* classify the operator */
1168             /* TODO: suffix operators */
1169             const oper_info *op;
1170             const oper_info *olast = NULL;
1171             size_t o;
1172             for (o = 0; o < operator_count; ++o) {
1173                 if ((!(operators[o].flags & OP_PREFIX) == wantop) &&
1174                     !(operators[o].flags & OP_SUFFIX) && /* remove this */
1175                     !strcmp(parser_tokval(parser), operators[o].op))
1176                 {
1177                     break;
1178                 }
1179             }
1180             if (o == operator_count) {
1181                 /* no operator found... must be the end of the statement */
1182                 break;
1183             }
1184             /* found an operator */
1185             op = &operators[o];
1186
1187             /* when declaring variables, a comma starts a new variable */
1188             if (op->id == opid1(',') && !parens && stopatcomma)
1189                 break;
1190
1191             if (sy.ops_count && !sy.ops[sy.ops_count-1].paren)
1192                 olast = &operators[sy.ops[sy.ops_count-1].etype-1];
1193
1194             while (olast && (
1195                     (op->prec < olast->prec) ||
1196                     (op->assoc == ASSOC_LEFT && op->prec <= olast->prec) ) )
1197             {
1198                 if (!parser_sy_pop(parser, &sy))
1199                     goto onerr;
1200                 if (sy.ops_count && !sy.ops[sy.ops_count-1].paren)
1201                     olast = &operators[sy.ops[sy.ops_count-1].etype-1];
1202                 else
1203                     olast = NULL;
1204             }
1205
1206             if (op->id == opid1('.') && opts_standard == COMPILER_GMQCC) {
1207                 /* for gmqcc standard: open up the namespace of the previous type */
1208                 ast_expression *prevex = sy.out[sy.out_count-1].out;
1209                 if (!prevex) {
1210                     parseerror(parser, "unexpected member operator");
1211                     goto onerr;
1212                 }
1213                 if (prevex->expression.vtype == TYPE_ENTITY)
1214                     parser->memberof = TYPE_ENTITY;
1215                 else if (prevex->expression.vtype == TYPE_VECTOR)
1216                     parser->memberof = TYPE_VECTOR;
1217                 else {
1218                     parseerror(parser, "type error: type has no members");
1219                     goto onerr;
1220                 }
1221                 gotmemberof = true;
1222             }
1223
1224             if (op->id == opid1('(')) {
1225                 if (wantop) {
1226                     DEBUGSHUNTDO(printf("push (\n"));
1227                     ++parens;
1228                     /* we expected an operator, this is the function-call operator */
1229                     if (!shunt_ops_add(&sy, syparen(parser_ctx(parser), 'f', sy.out_count-1))) {
1230                         parseerror(parser, "out of memory");
1231                         goto onerr;
1232                     }
1233                 } else {
1234                     ++parens;
1235                     if (!shunt_ops_add(&sy, syparen(parser_ctx(parser), 1, 0))) {
1236                         parseerror(parser, "out of memory");
1237                         goto onerr;
1238                     }
1239                     DEBUGSHUNTDO(printf("push (\n"));
1240                 }
1241                 wantop = false;
1242             } else {
1243                 DEBUGSHUNTDO(printf("push operator %s\n", op->op));
1244                 if (!shunt_ops_add(&sy, syop(parser_ctx(parser), op)))
1245                     goto onerr;
1246                 wantop = false;
1247             }
1248         }
1249         if (!parser_next(parser)) {
1250             goto onerr;
1251         }
1252         if (parser->tok == ';') {
1253             break;
1254         }
1255     }
1256
1257     while (sy.ops_count) {
1258         if (!parser_sy_pop(parser, &sy))
1259             goto onerr;
1260     }
1261
1262     parser->lex->flags.noops = true;
1263     if (!sy.out_count) {
1264         parseerror(parser, "empty expression");
1265         expr = NULL;
1266     } else
1267         expr = sy.out[0].out;
1268     MEM_VECTOR_CLEAR(&sy, out);
1269     MEM_VECTOR_CLEAR(&sy, ops);
1270     DEBUGSHUNTDO(printf("shunt done\n"));
1271     return expr;
1272
1273 onerr:
1274     parser->lex->flags.noops = true;
1275     MEM_VECTOR_CLEAR(&sy, out);
1276     MEM_VECTOR_CLEAR(&sy, ops);
1277     return NULL;
1278 }
1279
1280 static ast_expression* parser_expression(parser_t *parser, bool stopatcomma)
1281 {
1282     ast_expression *e = parser_expression_leave(parser, stopatcomma);
1283     if (!e)
1284         return NULL;
1285     if (!parser_next(parser)) {
1286         ast_delete(e);
1287         return NULL;
1288     }
1289     return e;
1290 }
1291
1292 static bool parser_parse_if(parser_t *parser, ast_block *block, ast_expression **out)
1293 {
1294     ast_ifthen *ifthen;
1295     ast_expression *cond, *ontrue, *onfalse = NULL;
1296
1297     lex_ctx ctx = parser_ctx(parser);
1298
1299     /* skip the 'if' and check for opening paren */
1300     if (!parser_next(parser) || parser->tok != '(') {
1301         parseerror(parser, "expected 'if' condition in parenthesis");
1302         return false;
1303     }
1304     /* parse into the expression */
1305     if (!parser_next(parser)) {
1306         parseerror(parser, "expected 'if' condition after opening paren");
1307         return false;
1308     }
1309     /* parse the condition */
1310     cond = parser_expression_leave(parser, false);
1311     if (!cond)
1312         return false;
1313     /* closing paren */
1314     if (parser->tok != ')') {
1315         parseerror(parser, "expected closing paren after 'if' condition");
1316         ast_delete(cond);
1317         return false;
1318     }
1319     /* parse into the 'then' branch */
1320     if (!parser_next(parser)) {
1321         parseerror(parser, "expected statement for on-true branch of 'if'");
1322         ast_delete(cond);
1323         return false;
1324     }
1325     ontrue = parser_parse_statement_or_block(parser);
1326     if (!ontrue) {
1327         ast_delete(cond);
1328         return false;
1329     }
1330     /* check for an else */
1331     if (!strcmp(parser_tokval(parser), "else")) {
1332         /* parse into the 'else' branch */
1333         if (!parser_next(parser)) {
1334             parseerror(parser, "expected on-false branch after 'else'");
1335             ast_delete(ontrue);
1336             ast_delete(cond);
1337             return false;
1338         }
1339         onfalse = parser_parse_statement_or_block(parser);
1340         if (!onfalse) {
1341             ast_delete(ontrue);
1342             ast_delete(cond);
1343             return false;
1344         }
1345     }
1346
1347     ifthen = ast_ifthen_new(ctx, cond, ontrue, onfalse);
1348     *out = (ast_expression*)ifthen;
1349     return true;
1350 }
1351
1352 static bool parser_parse_while(parser_t *parser, ast_block *block, ast_expression **out)
1353 {
1354     ast_loop *aloop;
1355     ast_expression *cond, *ontrue;
1356
1357     lex_ctx ctx = parser_ctx(parser);
1358
1359     /* skip the 'while' and check for opening paren */
1360     if (!parser_next(parser) || parser->tok != '(') {
1361         parseerror(parser, "expected 'while' condition in parenthesis");
1362         return false;
1363     }
1364     /* parse into the expression */
1365     if (!parser_next(parser)) {
1366         parseerror(parser, "expected 'while' condition after opening paren");
1367         return false;
1368     }
1369     /* parse the condition */
1370     cond = parser_expression_leave(parser, false);
1371     if (!cond)
1372         return false;
1373     /* closing paren */
1374     if (parser->tok != ')') {
1375         parseerror(parser, "expected closing paren after 'while' condition");
1376         ast_delete(cond);
1377         return false;
1378     }
1379     /* parse into the 'then' branch */
1380     if (!parser_next(parser)) {
1381         parseerror(parser, "expected while-loop body");
1382         ast_delete(cond);
1383         return false;
1384     }
1385     ontrue = parser_parse_statement_or_block(parser);
1386     if (!ontrue) {
1387         ast_delete(cond);
1388         return false;
1389     }
1390
1391     aloop = ast_loop_new(ctx, NULL, cond, NULL, NULL, ontrue);
1392     *out = (ast_expression*)aloop;
1393     return true;
1394 }
1395
1396 static bool parser_parse_dowhile(parser_t *parser, ast_block *block, ast_expression **out)
1397 {
1398     ast_loop *aloop;
1399     ast_expression *cond, *ontrue;
1400
1401     lex_ctx ctx = parser_ctx(parser);
1402
1403     /* skip the 'do' and get the body */
1404     if (!parser_next(parser)) {
1405         parseerror(parser, "expected loop body");
1406         return false;
1407     }
1408     ontrue = parser_parse_statement_or_block(parser);
1409     if (!ontrue)
1410         return false;
1411
1412     /* expect the "while" */
1413     if (parser->tok != TOKEN_KEYWORD ||
1414         strcmp(parser_tokval(parser), "while"))
1415     {
1416         parseerror(parser, "expected 'while' and condition");
1417         ast_delete(ontrue);
1418         return false;
1419     }
1420
1421     /* skip the 'while' and check for opening paren */
1422     if (!parser_next(parser) || parser->tok != '(') {
1423         parseerror(parser, "expected 'while' condition in parenthesis");
1424         ast_delete(ontrue);
1425         return false;
1426     }
1427     /* parse into the expression */
1428     if (!parser_next(parser)) {
1429         parseerror(parser, "expected 'while' condition after opening paren");
1430         ast_delete(ontrue);
1431         return false;
1432     }
1433     /* parse the condition */
1434     cond = parser_expression_leave(parser, false);
1435     if (!cond)
1436         return false;
1437     /* closing paren */
1438     if (parser->tok != ')') {
1439         parseerror(parser, "expected closing paren after 'while' condition");
1440         ast_delete(ontrue);
1441         ast_delete(cond);
1442         return false;
1443     }
1444     /* parse on */
1445     if (!parser_next(parser) || parser->tok != ';') {
1446         parseerror(parser, "expected semicolon after condition");
1447         ast_delete(ontrue);
1448         ast_delete(cond);
1449         return false;
1450     }
1451
1452     if (!parser_next(parser)) {
1453         parseerror(parser, "parse error");
1454         ast_delete(ontrue);
1455         ast_delete(cond);
1456         return false;
1457     }
1458
1459     aloop = ast_loop_new(ctx, NULL, NULL, cond, NULL, ontrue);
1460     *out = (ast_expression*)aloop;
1461     return true;
1462 }
1463
1464 static bool parser_parse_for(parser_t *parser, ast_block *block, ast_expression **out)
1465 {
1466     ast_loop *aloop;
1467     ast_expression *initexpr, *cond, *increment, *ontrue;
1468     size_t oldblocklocal;
1469
1470     lex_ctx ctx = parser_ctx(parser);
1471
1472     oldblocklocal = parser->blocklocal;
1473     parser->blocklocal = parser->locals_count;
1474
1475     initexpr  = NULL;
1476     cond      = NULL;
1477     increment = NULL;
1478     ontrue    = NULL;
1479
1480     /* skip the 'while' and check for opening paren */
1481     if (!parser_next(parser) || parser->tok != '(') {
1482         parseerror(parser, "expected 'for' expressions in parenthesis");
1483         goto onerr;
1484     }
1485     /* parse into the expression */
1486     if (!parser_next(parser)) {
1487         parseerror(parser, "expected 'for' initializer after opening paren");
1488         goto onerr;
1489     }
1490
1491     if (parser->tok == TOKEN_TYPENAME) {
1492         if (opts_standard != COMPILER_GMQCC) {
1493             if (parsewarning(parser, WARN_EXTENSIONS,
1494                              "current standard does not allow variable declarations in for-loop initializers"))
1495                 goto onerr;
1496         }
1497
1498         parseerror(parser, "TODO: assignment of new variables to be non-const");
1499         goto onerr;
1500         if (!parser_variable(parser, block))
1501             goto onerr;
1502     }
1503     else if (parser->tok != ';')
1504     {
1505         initexpr = parser_expression_leave(parser, false);
1506         if (!initexpr)
1507             goto onerr;
1508     }
1509
1510     /* move on to condition */
1511     if (parser->tok != ';') {
1512         parseerror(parser, "expected semicolon after for-loop initializer");
1513         goto onerr;
1514     }
1515     if (!parser_next(parser)) {
1516         parseerror(parser, "expected for-loop condition");
1517         goto onerr;
1518     }
1519
1520     /* parse the condition */
1521     if (parser->tok != ';') {
1522         cond = parser_expression_leave(parser, false);
1523         if (!cond)
1524             goto onerr;
1525     }
1526
1527     /* move on to incrementor */
1528     if (parser->tok != ';') {
1529         parseerror(parser, "expected semicolon after for-loop initializer");
1530         goto onerr;
1531     }
1532     if (!parser_next(parser)) {
1533         parseerror(parser, "expected for-loop condition");
1534         goto onerr;
1535     }
1536
1537     /* parse the incrementor */
1538     if (parser->tok != ')') {
1539         increment = parser_expression_leave(parser, false);
1540         if (!increment)
1541             goto onerr;
1542     }
1543
1544     /* closing paren */
1545     if (parser->tok != ')') {
1546         parseerror(parser, "expected closing paren after 'for-loop' incrementor");
1547         goto onerr;
1548     }
1549     /* parse into the 'then' branch */
1550     if (!parser_next(parser)) {
1551         parseerror(parser, "expected for-loop body");
1552         goto onerr;
1553     }
1554     ontrue = parser_parse_statement_or_block(parser);
1555     if (!ontrue) {
1556         goto onerr;
1557     }
1558
1559     aloop = ast_loop_new(ctx, initexpr, cond, NULL, increment, ontrue);
1560     *out = (ast_expression*)aloop;
1561
1562     while (parser->locals_count > parser->blocklocal)
1563         parser_pop_local(parser);
1564     parser->blocklocal = oldblocklocal;
1565     return true;
1566 onerr:
1567     if (initexpr)  ast_delete(initexpr);
1568     if (cond)      ast_delete(cond);
1569     if (increment) ast_delete(increment);
1570     while (parser->locals_count > parser->blocklocal)
1571         parser_pop_local(parser);
1572     parser->blocklocal = oldblocklocal;
1573     return false;
1574 }
1575
1576 static bool parser_parse_statement(parser_t *parser, ast_block *block, ast_expression **out)
1577 {
1578     if (parser->tok == TOKEN_TYPENAME)
1579     {
1580         /* local variable */
1581         if (!block) {
1582             parseerror(parser, "cannot declare a variable from here");
1583             return false;
1584         }
1585         if (opts_standard == COMPILER_QCC) {
1586             if (parsewarning(parser, WARN_EXTENSIONS, "missing 'local' keyword when declaring a local variable"))
1587                 return false;
1588         }
1589         if (!parser_variable(parser, block))
1590             return false;
1591         *out = NULL;
1592         return true;
1593     }
1594     else if (parser->tok == TOKEN_KEYWORD)
1595     {
1596         if (!strcmp(parser_tokval(parser), "local"))
1597         {
1598             if (!block) {
1599                 parseerror(parser, "cannot declare a local variable here");
1600                 return false;
1601             }
1602             if (!parser_next(parser)) {
1603                 parseerror(parser, "expected variable declaration");
1604                 return false;
1605             }
1606             if (!parser_variable(parser, block))
1607                 return false;
1608             *out = NULL;
1609             return true;
1610         }
1611         else if (!strcmp(parser_tokval(parser), "return"))
1612         {
1613             ast_expression *exp = NULL;
1614             ast_return     *ret = NULL;
1615             ast_value      *expected = parser->function->vtype;
1616
1617             if (!parser_next(parser)) {
1618                 parseerror(parser, "expected return expression");
1619                 return false;
1620             }
1621
1622             if (parser->tok != ';') {
1623                 exp = parser_expression(parser, false);
1624                 if (!exp)
1625                     return false;
1626
1627                 if (exp->expression.vtype != expected->expression.next->expression.vtype) {
1628                     parseerror(parser, "return with invalid expression");
1629                 }
1630
1631                 ret = ast_return_new(exp->expression.node.context, exp);
1632                 if (!ret) {
1633                     ast_delete(exp);
1634                     return false;
1635                 }
1636             } else {
1637                 if (!parser_next(parser))
1638                     parseerror(parser, "parse error");
1639                 if (expected->expression.next->expression.vtype != TYPE_VOID) {
1640                     if (opts_standard != COMPILER_GMQCC)
1641                         (void)!parsewarning(parser, WARN_MISSING_RETURN_VALUES, "return without value");
1642                     else
1643                         parseerror(parser, "return without value");
1644                 }
1645                 ret = ast_return_new(parser_ctx(parser), NULL);
1646             }
1647             *out = (ast_expression*)ret;
1648             return true;
1649         }
1650         else if (!strcmp(parser_tokval(parser), "if"))
1651         {
1652             return parser_parse_if(parser, block, out);
1653         }
1654         else if (!strcmp(parser_tokval(parser), "while"))
1655         {
1656             return parser_parse_while(parser, block, out);
1657         }
1658         else if (!strcmp(parser_tokval(parser), "do"))
1659         {
1660             return parser_parse_dowhile(parser, block, out);
1661         }
1662         else if (!strcmp(parser_tokval(parser), "for"))
1663         {
1664             if (opts_standard == COMPILER_QCC) {
1665                 if (parsewarning(parser, WARN_EXTENSIONS, "for loops are not recognized in the original Quake C standard, to enable try an alternate standard --std=?"))
1666                     return false;
1667             }
1668             return parser_parse_for(parser, block, out);
1669         }
1670         parseerror(parser, "Unexpected keyword");
1671         return false;
1672     }
1673     else if (parser->tok == '{')
1674     {
1675         ast_block *inner;
1676         inner = parser_parse_block(parser);
1677         if (!inner)
1678             return false;
1679         *out = (ast_expression*)inner;
1680         return true;
1681     }
1682     else
1683     {
1684         ast_expression *exp = parser_expression(parser, false);
1685         if (!exp)
1686             return false;
1687         *out = exp;
1688         return true;
1689     }
1690 }
1691
1692 static void parser_pop_local(parser_t *parser)
1693 {
1694     parser->locals_count--;
1695     mem_d(parser->locals[parser->locals_count].name);
1696 }
1697
1698 static ast_block* parser_parse_block(parser_t *parser)
1699 {
1700     size_t oldblocklocal;
1701     ast_block *block = NULL;
1702
1703     oldblocklocal = parser->blocklocal;
1704     parser->blocklocal = parser->locals_count;
1705
1706     if (!parser_next(parser)) { /* skip the '{' */
1707         parseerror(parser, "expected function body");
1708         goto cleanup;
1709     }
1710
1711     block = ast_block_new(parser_ctx(parser));
1712
1713     while (parser->tok != TOKEN_EOF && parser->tok < TOKEN_ERROR)
1714     {
1715         ast_expression *expr;
1716         if (parser->tok == '}')
1717             break;
1718
1719         if (!parser_parse_statement(parser, block, &expr)) {
1720             parseerror(parser, "parse error");
1721             ast_block_delete(block);
1722             block = NULL;
1723             goto cleanup;
1724         }
1725         if (!expr)
1726             continue;
1727         if (!ast_block_exprs_add(block, expr)) {
1728             ast_delete(expr);
1729             ast_block_delete(block);
1730             block = NULL;
1731             goto cleanup;
1732         }
1733     }
1734
1735     if (parser->tok != '}') {
1736         ast_block_delete(block);
1737         block = NULL;
1738     } else {
1739         (void)parser_next(parser);
1740     }
1741
1742 cleanup:
1743     while (parser->locals_count > parser->blocklocal)
1744         parser_pop_local(parser);
1745     parser->blocklocal = oldblocklocal;
1746     /* unroll the local vector */
1747     return block;
1748 }
1749
1750 static ast_expression* parser_parse_statement_or_block(parser_t *parser)
1751 {
1752     ast_expression *expr = NULL;
1753     if (parser->tok == '{')
1754         return (ast_expression*)parser_parse_block(parser);
1755     if (!parser_parse_statement(parser, NULL, &expr))
1756         return NULL;
1757     return expr;
1758 }
1759
1760 static bool parser_variable(parser_t *parser, ast_block *localblock)
1761 {
1762     bool          isfunc = false;
1763     ast_function *func = NULL;
1764     lex_ctx       ctx;
1765     ast_value    *var;
1766     varentry_t    varent;
1767     ast_expression *olddecl;
1768
1769     bool hadproto;
1770
1771     int basetype = parser_token(parser)->constval.t;
1772
1773     while (true)
1774     {
1775         hadproto = false;
1776
1777         if (!parser_next(parser)) { /* skip basetype or comma */
1778             parseerror(parser, "expected variable declaration");
1779             return false;
1780         }
1781
1782         olddecl = NULL;
1783         isfunc  = false;
1784         func    = NULL;
1785         ctx = parser_ctx(parser);
1786         var = parser_parse_type(parser, basetype, &isfunc);
1787
1788         if (!var)
1789             return false;
1790
1791         if (parser->tok != TOKEN_IDENT) {
1792             parseerror(parser, "expected variable name\n");
1793             return false;
1794         }
1795
1796         if (!isfunc) {
1797             if (!localblock && (olddecl = parser_find_global(parser, parser_tokval(parser)))) {
1798                 ast_value_delete(var);
1799                 parseerror(parser, "global %s already declared here: %s:%i\n",
1800                            parser_tokval(parser), ast_ctx(olddecl).file, (int)ast_ctx(olddecl).line);
1801                 return false;
1802             }
1803
1804             if (localblock && parser_find_local(parser, parser_tokval(parser), parser->blocklocal)) {
1805                 ast_value_delete(var);
1806                 parseerror(parser, "local %s already declared here: %s:%i\n",
1807                            parser_tokval(parser), ast_ctx(olddecl).file, (int)ast_ctx(olddecl).line);
1808                 return false;
1809             }
1810         }
1811
1812         if (!ast_value_set_name(var, parser_tokval(parser))) {
1813             parseerror(parser, "failed to set variable name\n");
1814             ast_value_delete(var);
1815             return false;
1816         }
1817
1818         if (isfunc) {
1819             /* a function was defined */
1820             ast_value *fval;
1821             ast_value *proto = NULL;
1822
1823             if (!localblock)
1824                 olddecl = parser_find_global(parser, parser_tokval(parser));
1825             else
1826                 olddecl = parser_find_local(parser, parser_tokval(parser), parser->blocklocal);
1827
1828             if (olddecl) {
1829                 /* we had a prototype */
1830                 if (!ast_istype(olddecl, ast_value)) {
1831                     /* theoretically not possible you think?
1832                      * well:
1833                      * vector v;
1834                      * void() v_x = {}
1835                      * got it?
1836                      */
1837                     parseerror(parser, "cannot declare a function with the same name as a vector's member: %s",
1838                                parser_tokval(parser));
1839                     ast_value_delete(var);
1840                     return false;
1841                 }
1842
1843                 proto = (ast_value*)olddecl;
1844             }
1845
1846             /* turn var into a value of TYPE_FUNCTION, with the old var
1847              * as return type
1848              */
1849             fval = ast_value_new(ctx, var->name, TYPE_FUNCTION);
1850             func = ast_function_new(ctx, var->name, fval);
1851             if (!fval || !func) {
1852                 ast_value_delete(var);
1853                 if (fval) ast_value_delete(fval);
1854                 if (func) ast_function_delete(func);
1855                 return false;
1856             }
1857
1858             fval->expression.next = (ast_expression*)var;
1859             MEM_VECTOR_MOVE(&var->expression, params, &fval->expression, params);
1860
1861             /* we compare the type late here, but it's easier than
1862              * messing with the parameter-vector etc. earlier
1863              */
1864             if (proto) {
1865                 size_t param;
1866                 if (!ast_compare_type((ast_expression*)proto, (ast_expression*)fval)) {
1867                     parseerror(parser, "conflicting types for `%s`, previous declaration was here: %s:%i",
1868                                proto->name,
1869                                ast_ctx(proto).file, ast_ctx(proto).line);
1870                     ast_function_delete(func);
1871                     ast_value_delete(fval);
1872                     return false;
1873                 }
1874                 /* copy over the parameter names */
1875                 for (param = 0; param < fval->expression.params_count; ++param)
1876                     ast_value_set_name(proto->expression.params[param], fval->expression.params[param]->name);
1877
1878                 /* now ditch the rest of the new data */
1879                 ast_function_delete(func);
1880                 ast_value_delete(fval);
1881                 fval = proto;
1882                 func = proto->constval.vfunc;
1883                 hadproto = true;
1884             }
1885             else
1886             {
1887                 if (!parser_t_functions_add(parser, func)) {
1888                     ast_function_delete(func);
1889                     ast_value_delete(fval);
1890                     return false;
1891                 }
1892             }
1893
1894             var = fval;
1895         }
1896
1897         if (!hadproto) {
1898             varent.name = util_strdup(var->name);
1899             varent.var = (ast_expression*)var;
1900             if (var->expression.vtype == TYPE_VECTOR)
1901             {
1902                 size_t len = strlen(varent.name);
1903                 varentry_t vx, vy, vz;
1904                 vx.var = (ast_expression*)ast_member_new(var->expression.node.context, (ast_expression*)var, 0);
1905                 vy.var = (ast_expression*)ast_member_new(var->expression.node.context, (ast_expression*)var, 1);
1906                 vz.var = (ast_expression*)ast_member_new(var->expression.node.context, (ast_expression*)var, 2);
1907                 vx.name = (char*)mem_a(len+3);
1908                 vy.name = (char*)mem_a(len+3);
1909                 vz.name = (char*)mem_a(len+3);
1910                 memcpy(vx.name, varent.name, len);
1911                 memcpy(vy.name, varent.name, len);
1912                 memcpy(vz.name, varent.name, len);
1913                 vx.name[len] = vy.name[len] = vz.name[len] = '_';
1914                 vx.name[len+1] = 'x';
1915                 vy.name[len+1] = 'y';
1916                 vz.name[len+1] = 'z';
1917                 vx.name[len+2] = vy.name[len+2] = vz.name[len+2] = 0;
1918
1919                 if (!localblock) {
1920                     (void)!parser_t_globals_add(parser, varent);
1921                     (void)!parser_t_globals_add(parser, vx);
1922                     (void)!parser_t_globals_add(parser, vy);
1923                     (void)!parser_t_globals_add(parser, vz);
1924                 } else {
1925                     (void)!parser_t_locals_add(parser, varent);
1926                     (void)!parser_t_locals_add(parser, vx);
1927                     (void)!parser_t_locals_add(parser, vy);
1928                     (void)!parser_t_locals_add(parser, vz);
1929                     if (!ast_block_locals_add(localblock, var) ||
1930                         !ast_block_collect(localblock, vx.var) ||
1931                         !ast_block_collect(localblock, vy.var) ||
1932                         !ast_block_collect(localblock, vz.var))
1933                     {
1934                         parser_pop_local(parser);
1935                         parser_pop_local(parser);
1936                         parser_pop_local(parser);
1937                         parser_pop_local(parser);
1938                         ast_value_delete(var);
1939                         return false;
1940                     }
1941                 }
1942             }
1943             else
1944             {
1945                 if ( (!localblock && !parser_t_globals_add(parser, varent)) ||
1946                      ( localblock && !parser_t_locals_add(parser, varent)) )
1947                 {
1948                     ast_value_delete(var);
1949                     return false;
1950                 }
1951                 if (localblock && !ast_block_locals_add(localblock, var))
1952                 {
1953                     parser_pop_local(parser);
1954                     ast_value_delete(var);
1955                     return false;
1956                 }
1957             }
1958         }
1959
1960         if (!parser_next(parser)) {
1961             ast_value_delete(var);
1962             return false;
1963         }
1964
1965         if (parser->tok == ';') {
1966             if (!parser_next(parser))
1967                 return parser->tok == TOKEN_EOF;
1968             return true;
1969         }
1970
1971         if (parser->tok == ',') {
1972             /* another var */
1973             continue;
1974         }
1975
1976         if (parser->tok != '=') {
1977             parseerror(parser, "expected '=' or ';'");
1978             return false;
1979         }
1980
1981         if (!parser_next(parser))
1982             return false;
1983
1984         if (parser->tok == '#') {
1985             if (localblock) {
1986                 parseerror(parser, "cannot declare builtins within functions");
1987                 return false;
1988             }
1989             if (!isfunc || !func) {
1990                 parseerror(parser, "unexpected builtin number, '%s' is not a function", var->name);
1991                 return false;
1992             }
1993             if (!parser_next(parser)) {
1994                 parseerror(parser, "expected builtin number");
1995                 return false;
1996             }
1997             if (parser->tok != TOKEN_INTCONST) {
1998                 parseerror(parser, "builtin number must be an integer constant");
1999                 return false;
2000             }
2001             if (parser_token(parser)->constval.i <= 0) {
2002                 parseerror(parser, "builtin number must be positive integer greater than zero");
2003                 return false;
2004             }
2005
2006             func->builtin = -parser_token(parser)->constval.i;
2007
2008             if (!parser_next(parser))
2009                 return false;
2010         } else if (parser->tok == '{') {
2011             /* function body */
2012             ast_block *block;
2013             ast_function *old = parser->function;
2014
2015             if (localblock) {
2016                 parseerror(parser, "cannot declare functions within functions");
2017                 return false;
2018             }
2019
2020             parser->function = func;
2021             block = parser_parse_block(parser);
2022             parser->function = old;
2023
2024             if (!block)
2025                 return false;
2026
2027             if (!ast_function_blocks_add(func, block)) {
2028                 ast_block_delete(block);
2029                 return false;
2030             }
2031
2032             if (parser->tok == ';')
2033                 return parser_next(parser) || parser->tok == TOKEN_EOF;
2034             else if (opts_standard == COMPILER_QCC)
2035                 parseerror(parser, "missing semicolon after function body (mandatory with -std=qcc)");
2036             return true;
2037         } else {
2038             ast_expression *cexp;
2039             ast_value      *cval;
2040
2041             cexp = parser_expression_leave(parser, true);
2042             cval = (ast_value*)cexp;
2043             if (!ast_istype(cval, ast_value) || !cval->isconst)
2044                 parseerror(parser, "cannot initialize a global constant variable with a non-constant expression");
2045             else
2046             {
2047                 var->isconst = true;
2048                 memcpy(&var->constval, &cval->constval, sizeof(var->constval));
2049                 memset(&cval->constval, 0, sizeof(cval->constval));
2050                 ast_unref(cval);
2051             }
2052         }
2053
2054         if (parser->tok == ',') {
2055             /* another */
2056             continue;
2057         }
2058
2059         if (parser->tok != ';') {
2060             parseerror(parser, "missing semicolon");
2061             return false;
2062         }
2063
2064         (void)parser_next(parser);
2065
2066         return true;
2067     }
2068 }
2069
2070 static bool parser_do(parser_t *parser)
2071 {
2072     if (parser->tok == TOKEN_TYPENAME)
2073     {
2074         return parser_variable(parser, NULL);
2075     }
2076     else if (parser->tok == TOKEN_KEYWORD)
2077     {
2078         /* handle 'var' and 'const' */
2079         return false;
2080     }
2081     else if (parser->tok == '.')
2082     {
2083         ast_value *var;
2084         ast_value *typevar;
2085         ast_value *fld;
2086         ast_expression *oldex;
2087         bool       isfunc = false;
2088         int        basetype;
2089         lex_ctx    ctx = parser_ctx(parser);
2090         varentry_t varent;
2091
2092         /* entity-member declaration */
2093         if (!parser_next(parser) || parser->tok != TOKEN_TYPENAME) {
2094             parseerror(parser, "expected member variable definition");
2095             return false;
2096         }
2097
2098         /* remember the base/return type */
2099         basetype = parser_token(parser)->constval.t;
2100
2101         /* parse into the declaration */
2102         if (!parser_next(parser)) {
2103             parseerror(parser, "expected field def");
2104             return false;
2105         }
2106
2107         /* parse the field type fully */
2108         typevar = var = parser_parse_type(parser, basetype, &isfunc);
2109         if (!var)
2110             return false;
2111
2112         while (true) {
2113             var = ast_value_copy(typevar);
2114             /* now the field name */
2115             if (parser->tok != TOKEN_IDENT) {
2116                 parseerror(parser, "expected field name");
2117                 ast_delete(var);
2118                 return false;
2119             }
2120
2121             /* check for an existing field
2122              * in original qc we also have to check for an existing
2123              * global named like the field
2124              */
2125             if (opts_standard == COMPILER_QCC) {
2126                 if (parser_find_global(parser, parser_tokval(parser))) {
2127                     parseerror(parser, "cannot declare a field and a global of the same name with -std=qcc");
2128                     ast_delete(var);
2129                     return false;
2130                 }
2131             }
2132
2133             if (isfunc) {
2134                 ast_value *fval;
2135                 fval = ast_value_new(ctx, var->name, TYPE_FUNCTION);
2136                 if (!fval) {
2137                     ast_value_delete(var);
2138                     return false;
2139                 }
2140                 fval->expression.next = (ast_expression*)var;
2141                 MEM_VECTOR_MOVE(&var->expression, params, &fval->expression, params);
2142                 var = fval;
2143             }
2144
2145             /* turn it into a field */
2146             fld = ast_value_new(ctx, parser_tokval(parser), TYPE_FIELD);
2147             fld->expression.next = (ast_expression*)var;
2148
2149             if ( (oldex = parser_find_field(parser, parser_tokval(parser)))) {
2150                 if (ast_istype(oldex, ast_member)) {
2151                     parseerror(parser, "cannot declare a field with the same name as a vector component, component %s has been declared here: %s:%i",
2152                                parser_tokval(parser), ast_ctx(oldex).file, (int)ast_ctx(oldex).line);
2153                     ast_delete(fld);
2154                     return false;
2155                 }
2156                 if (!ast_istype(oldex, ast_value)) {
2157                     /* not possible / sanity check */
2158                     parseerror(parser, "internal error: %s is not an ast_value", parser_tokval(parser));
2159                     ast_delete(fld);
2160                     return false;
2161                 }
2162
2163                 if (!ast_compare_type(oldex, (ast_expression*)fld)) {
2164                     parseerror(parser, "field %s has previously been declared with a different type here: %s:%i",
2165                                parser_tokval(parser), ast_ctx(oldex).file, (int)ast_ctx(oldex).line);
2166                     ast_delete(fld);
2167                     return false;
2168                 } else {
2169                     if (parsewarning(parser, WARN_FIELD_REDECLARED, "field %s has already been declared here: %s:%i",
2170                                      parser_tokval(parser), ast_ctx(oldex).file, (int)ast_ctx(oldex).line))
2171                     {
2172                         ast_delete(fld);
2173                         return false;
2174                     }
2175                 }
2176
2177                 ast_delete(fld);
2178                 goto nextfield;
2179             }
2180
2181             varent.var = (ast_expression*)fld;
2182             varent.name = util_strdup(fld->name);
2183             (void)!parser_t_fields_add(parser, varent);
2184
2185             if (var->expression.vtype == TYPE_VECTOR)
2186             {
2187                 /* create _x, _y and _z fields as well */
2188                 size_t len;
2189                 varentry_t vx, vy, vz;
2190
2191                 len = strlen(varent.name);
2192                 vx.var = (ast_expression*)ast_member_new(ast_ctx(fld), (ast_expression*)fld, 0);
2193                 vy.var = (ast_expression*)ast_member_new(ast_ctx(fld), (ast_expression*)fld, 1);
2194                 vz.var = (ast_expression*)ast_member_new(ast_ctx(fld), (ast_expression*)fld, 2);
2195                 vx.name = (char*)mem_a(len+3);
2196                 vy.name = (char*)mem_a(len+3);
2197                 vz.name = (char*)mem_a(len+3);
2198                 memcpy(vx.name, varent.name, len);
2199                 memcpy(vy.name, varent.name, len);
2200                 memcpy(vz.name, varent.name, len);
2201                 vx.name[len] = vy.name[len] = vz.name[len] = '_';
2202                 vx.name[len+1] = 'x';
2203                 vy.name[len+1] = 'y';
2204                 vz.name[len+1] = 'z';
2205                 vx.name[len+2] = vy.name[len+2] = vz.name[len+2] = 0;
2206                 (void)!parser_t_fields_add(parser, vx);
2207                 (void)!parser_t_fields_add(parser, vy);
2208                 (void)!parser_t_fields_add(parser, vz);
2209             }
2210
2211 nextfield:
2212             if (!parser_next(parser)) {
2213                 parseerror(parser, "expected semicolon or another field name");
2214                 return false;
2215             }
2216             if (parser->tok == ';')
2217                 break;
2218             if (parser->tok != ',' || !parser_next(parser)) {
2219                 parseerror(parser, "expected semicolon or another field name");
2220                 return false;
2221             }
2222         }
2223         ast_delete(typevar);
2224
2225         /* skip the semicolon */
2226         if (!parser_next(parser))
2227             return parser->tok == TOKEN_EOF;
2228
2229         return true;
2230     }
2231     else if (parser->tok == '$')
2232     {
2233         if (!parser_next(parser)) {
2234             parseerror(parser, "parse error");
2235             return false;
2236         }
2237     }
2238     else
2239     {
2240         parseerror(parser, "unexpected token: %s", parser->lex->tok->value);
2241         return false;
2242     }
2243     return true;
2244 }
2245
2246 static parser_t *parser;
2247
2248 bool parser_init()
2249 {
2250     parser = (parser_t*)mem_a(sizeof(parser_t));
2251     if (!parser)
2252         return false;
2253
2254     memset(parser, 0, sizeof(*parser));
2255     return true;
2256 }
2257
2258 bool parser_compile(const char *filename)
2259 {
2260     parser->lex = lex_open(filename);
2261     if (!parser->lex) {
2262         printf("failed to open file \"%s\"\n", filename);
2263         return false;
2264     }
2265
2266     /* initial lexer/parser state */
2267     parser->lex->flags.noops = true;
2268
2269     if (parser_next(parser))
2270     {
2271         while (parser->tok != TOKEN_EOF && parser->tok < TOKEN_ERROR)
2272         {
2273             if (!parser_do(parser)) {
2274                 if (parser->tok == TOKEN_EOF)
2275                     parseerror(parser, "unexpected eof");
2276                 else if (!parser->errors)
2277                     parseerror(parser, "parse error\n");
2278                 lex_close(parser->lex);
2279                 parser->lex = NULL;
2280                 return false;
2281             }
2282         }
2283     }
2284
2285     lex_close(parser->lex);
2286     parser->lex = NULL;
2287
2288     return !parser->errors;
2289 }
2290
2291 void parser_cleanup()
2292 {
2293     size_t i;
2294     for (i = 0; i < parser->functions_count; ++i) {
2295         ast_delete(parser->functions[i]);
2296     }
2297     for (i = 0; i < parser->imm_vector_count; ++i) {
2298         ast_delete(parser->imm_vector[i]);
2299     }
2300     for (i = 0; i < parser->imm_string_count; ++i) {
2301         ast_delete(parser->imm_string[i]);
2302     }
2303     for (i = 0; i < parser->imm_float_count; ++i) {
2304         ast_delete(parser->imm_float[i]);
2305     }
2306     for (i = 0; i < parser->fields_count; ++i) {
2307         ast_delete(parser->fields[i].var);
2308         mem_d(parser->fields[i].name);
2309     }
2310     for (i = 0; i < parser->globals_count; ++i) {
2311         ast_delete(parser->globals[i].var);
2312         mem_d(parser->globals[i].name);
2313     }
2314     MEM_VECTOR_CLEAR(parser, functions);
2315     MEM_VECTOR_CLEAR(parser, imm_vector);
2316     MEM_VECTOR_CLEAR(parser, imm_string);
2317     MEM_VECTOR_CLEAR(parser, imm_float);
2318     MEM_VECTOR_CLEAR(parser, globals);
2319     MEM_VECTOR_CLEAR(parser, fields);
2320     MEM_VECTOR_CLEAR(parser, locals);
2321
2322     mem_d(parser);
2323 }
2324
2325 bool parser_finish(const char *output)
2326 {
2327     size_t i;
2328     ir_builder *ir;
2329
2330     if (!parser->errors)
2331     {
2332         ir = ir_builder_new("gmqcc_out");
2333         if (!ir) {
2334             printf("failed to allocate builder\n");
2335             return false;
2336         }
2337
2338         for (i = 0; i < parser->imm_float_count; ++i) {
2339             if (!ast_global_codegen(parser->imm_float[i], ir)) {
2340                 printf("failed to generate global %s\n", parser->imm_float[i]->name);
2341                 ir_builder_delete(ir);
2342                 return false;
2343             }
2344         }
2345         for (i = 0; i < parser->imm_string_count; ++i) {
2346             if (!ast_global_codegen(parser->imm_string[i], ir)) {
2347                 printf("failed to generate global %s\n", parser->imm_string[i]->name);
2348                 ir_builder_delete(ir);
2349                 return false;
2350             }
2351         }
2352         for (i = 0; i < parser->imm_vector_count; ++i) {
2353             if (!ast_global_codegen(parser->imm_vector[i], ir)) {
2354                 printf("failed to generate global %s\n", parser->imm_vector[i]->name);
2355                 ir_builder_delete(ir);
2356                 return false;
2357             }
2358         }
2359         for (i = 0; i < parser->fields_count; ++i) {
2360             ast_value *field;
2361             bool isconst;
2362             if (!ast_istype(parser->fields[i].var, ast_value))
2363                 continue;
2364             field = (ast_value*)parser->fields[i].var;
2365             isconst = field->isconst;
2366             field->isconst = false;
2367             if (!ast_global_codegen((ast_value*)field, ir)) {
2368                 printf("failed to generate field %s\n", field->name);
2369                 ir_builder_delete(ir);
2370                 return false;
2371             }
2372             if (isconst) {
2373                 ir_value *ifld;
2374                 ast_expression *subtype;
2375                 field->isconst = true;
2376                 subtype = field->expression.next;
2377                 ifld = ir_builder_create_field(ir, field->name, subtype->expression.vtype);
2378                 if (subtype->expression.vtype == TYPE_FIELD)
2379                     ifld->fieldtype = subtype->expression.next->expression.vtype;
2380                 else if (subtype->expression.vtype == TYPE_FUNCTION)
2381                     ifld->outtype = subtype->expression.next->expression.vtype;
2382                 (void)!ir_value_set_field(field->ir_v, ifld);
2383             }
2384         }
2385         for (i = 0; i < parser->globals_count; ++i) {
2386             if (!ast_istype(parser->globals[i].var, ast_value))
2387                 continue;
2388             if (!ast_global_codegen((ast_value*)(parser->globals[i].var), ir)) {
2389                 printf("failed to generate global %s\n", parser->globals[i].name);
2390                 ir_builder_delete(ir);
2391                 return false;
2392             }
2393         }
2394         for (i = 0; i < parser->functions_count; ++i) {
2395             if (!ast_function_codegen(parser->functions[i], ir)) {
2396                 printf("failed to generate function %s\n", parser->functions[i]->name);
2397                 ir_builder_delete(ir);
2398                 return false;
2399             }
2400             if (!ir_function_finalize(parser->functions[i]->ir_func)) {
2401                 printf("failed to finalize function %s\n", parser->functions[i]->name);
2402                 ir_builder_delete(ir);
2403                 return false;
2404             }
2405         }
2406
2407         if (opts_dump)
2408             ir_builder_dump(ir, printf);
2409
2410         if (!ir_builder_generate(ir, output)) {
2411             printf("*** failed to generate output file\n");
2412             ir_builder_delete(ir);
2413             return false;
2414         }
2415
2416         ir_builder_delete(ir);
2417         return true;
2418     }
2419
2420     printf("*** there were compile errors\n");
2421     return false;
2422 }