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