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