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