]> git.xonotic.org Git - xonotic/gmqcc.git/blob - parser.c
even in non-qcc mode we need to search the variables for fields because of field...
[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 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                     /* still get vars first since there could be a fieldpointer */
970                     var = parser_find_var(parser, parser_tokval(parser));
971                     if (!var)
972                         var = parser_find_field(parser, parser_tokval(parser));
973                 }
974                 else if (parser->memberof == TYPE_VECTOR)
975                 {
976                     parseerror(parser, "TODO: implement effective vector member access");
977                     goto onerr;
978                 }
979                 else if (parser->memberof) {
980                     parseerror(parser, "namespace for member not found");
981                     goto onerr;
982                 }
983                 else
984                     var = parser_find_var(parser, parser_tokval(parser));
985             } else {
986                 var = parser_find_var(parser, parser_tokval(parser));
987                 if (!var)
988                     var = parser_find_field(parser, parser_tokval(parser));
989             }
990             if (!var) {
991                 parseerror(parser, "unexpected ident: %s", parser_tokval(parser));
992                 goto onerr;
993             }
994             if (!shunt_out_add(&sy, syexp(parser_ctx(parser), var))) {
995                 parseerror(parser, "out of memory");
996                 goto onerr;
997             }
998             DEBUGSHUNTDO(printf("push %s\n", parser_tokval(parser)));
999         }
1000         else if (parser->tok == TOKEN_FLOATCONST) {
1001             ast_value *val;
1002             if (wantop) {
1003                 parseerror(parser, "expected operator or end of statement, got constant");
1004                 goto onerr;
1005             }
1006             wantop = true;
1007             val = parser_const_float(parser, (parser_token(parser)->constval.f));
1008             if (!val)
1009                 return false;
1010             if (!shunt_out_add(&sy, syexp(parser_ctx(parser), (ast_expression*)val))) {
1011                 parseerror(parser, "out of memory");
1012                 goto onerr;
1013             }
1014             DEBUGSHUNTDO(printf("push %g\n", parser_token(parser)->constval.f));
1015         }
1016         else if (parser->tok == TOKEN_INTCONST) {
1017             ast_value *val;
1018             if (wantop) {
1019                 parseerror(parser, "expected operator or end of statement, got constant");
1020                 goto onerr;
1021             }
1022             wantop = true;
1023             val = parser_const_float(parser, (double)(parser_token(parser)->constval.i));
1024             if (!val)
1025                 return false;
1026             if (!shunt_out_add(&sy, syexp(parser_ctx(parser), (ast_expression*)val))) {
1027                 parseerror(parser, "out of memory");
1028                 goto onerr;
1029             }
1030             DEBUGSHUNTDO(printf("push %i\n", parser_token(parser)->constval.i));
1031         }
1032         else if (parser->tok == TOKEN_STRINGCONST) {
1033             ast_value *val;
1034             if (wantop) {
1035                 parseerror(parser, "expected operator or end of statement, got constant");
1036                 goto onerr;
1037             }
1038             wantop = true;
1039             val = parser_const_string(parser, parser_tokval(parser));
1040             if (!val)
1041                 return false;
1042             if (!shunt_out_add(&sy, syexp(parser_ctx(parser), (ast_expression*)val))) {
1043                 parseerror(parser, "out of memory");
1044                 goto onerr;
1045             }
1046             DEBUGSHUNTDO(printf("push string\n"));
1047         }
1048         else if (parser->tok == TOKEN_VECTORCONST) {
1049             ast_value *val;
1050             if (wantop) {
1051                 parseerror(parser, "expected operator or end of statement, got constant");
1052                 goto onerr;
1053             }
1054             wantop = true;
1055             val = parser_const_vector(parser, parser_token(parser)->constval.v);
1056             if (!val)
1057                 return false;
1058             if (!shunt_out_add(&sy, syexp(parser_ctx(parser), (ast_expression*)val))) {
1059                 parseerror(parser, "out of memory");
1060                 goto onerr;
1061             }
1062             DEBUGSHUNTDO(printf("push '%g %g %g'\n",
1063                                 parser_token(parser)->constval.v.x,
1064                                 parser_token(parser)->constval.v.y,
1065                                 parser_token(parser)->constval.v.z));
1066         }
1067         else if (parser->tok == '(') {
1068             if (wantop) {
1069                 DEBUGSHUNTDO(printf("push (\n"));
1070                 ++parens;
1071                 /* we expected an operator, this is the function-call operator */
1072                 if (!shunt_ops_add(&sy, syparen(parser_ctx(parser), 'f', sy.out_count-1))) {
1073                     parseerror(parser, "out of memory");
1074                     goto onerr;
1075                 }
1076             } else {
1077                 ++parens;
1078                 if (!shunt_ops_add(&sy, syparen(parser_ctx(parser), 1, 0))) {
1079                     parseerror(parser, "out of memory");
1080                     goto onerr;
1081                 }
1082                 DEBUGSHUNTDO(printf("push (\n"));
1083             }
1084             wantop = false;
1085         }
1086         else if (parser->tok == ')') {
1087             if (wantop) {
1088                 DEBUGSHUNTDO(printf("do[op] )\n"));
1089                 --parens;
1090                 if (parens < 0)
1091                     break;
1092                 /* we do expect an operator next */
1093                 /* closing an opening paren */
1094                 if (!parser_close_paren(parser, &sy, false))
1095                     goto onerr;
1096             } else {
1097                 DEBUGSHUNTDO(printf("do[nop] )\n"));
1098                 --parens;
1099                 if (parens < 0)
1100                     break;
1101                 /* allowed for function calls */
1102                 if (!parser_close_paren(parser, &sy, true))
1103                     goto onerr;
1104             }
1105             wantop = true;
1106         }
1107         else if (parser->tok != TOKEN_OPERATOR) {
1108             if (wantop) {
1109                 parseerror(parser, "expected operator or end of statement");
1110                 goto onerr;
1111             }
1112             break;
1113         }
1114         else
1115         {
1116             /* classify the operator */
1117             /* TODO: suffix operators */
1118             const oper_info *op;
1119             const oper_info *olast = NULL;
1120             size_t o;
1121             for (o = 0; o < operator_count; ++o) {
1122                 if ((!(operators[o].flags & OP_PREFIX) == wantop) &&
1123                     !(operators[o].flags & OP_SUFFIX) && /* remove this */
1124                     !strcmp(parser_tokval(parser), operators[o].op))
1125                 {
1126                     break;
1127                 }
1128             }
1129             wantop = false;
1130             if (o == operator_count) {
1131                 /* no operator found... must be the end of the statement */
1132                 break;
1133             }
1134             /* found an operator */
1135             op = &operators[o];
1136
1137             /* when declaring variables, a comma starts a new variable */
1138             if (op->id == opid1(',') && !parens && stopatcomma)
1139                 break;
1140
1141             if (op->id == opid1('.')) {
1142                 /* for gmqcc standard: open up the namespace of the previous type */
1143                 ast_expression *prevex = sy.out[sy.out_count-1].out;
1144                 if (!prevex) {
1145                     parseerror(parser, "unexpected member operator");
1146                     goto onerr;
1147                 }
1148                 if (prevex->expression.vtype == TYPE_ENTITY)
1149                     parser->memberof = TYPE_ENTITY;
1150                 else if (prevex->expression.vtype == TYPE_VECTOR)
1151                     parser->memberof = TYPE_VECTOR;
1152                 else {
1153                     parseerror(parser, "type error: type has no members");
1154                     goto onerr;
1155                 }
1156                 gotmemberof = true;
1157             }
1158
1159             if (sy.ops_count && !sy.ops[sy.ops_count-1].paren)
1160                 olast = &operators[sy.ops[sy.ops_count-1].etype-1];
1161
1162             while (olast && (
1163                     (op->prec < olast->prec) ||
1164                     (op->assoc == ASSOC_LEFT && op->prec <= olast->prec) ) )
1165             {
1166                 if (!parser_sy_pop(parser, &sy))
1167                     goto onerr;
1168                 if (sy.ops_count && !sy.ops[sy.ops_count-1].paren)
1169                     olast = &operators[sy.ops[sy.ops_count-1].etype-1];
1170                 else
1171                     olast = NULL;
1172             }
1173
1174             DEBUGSHUNTDO(printf("push operator %s\n", op->op));
1175             if (!shunt_ops_add(&sy, syop(parser_ctx(parser), op)))
1176                 goto onerr;
1177         }
1178         if (!parser_next(parser)) {
1179             goto onerr;
1180         }
1181         if (parser->tok == ';') {
1182             break;
1183         }
1184     }
1185
1186     while (sy.ops_count) {
1187         if (!parser_sy_pop(parser, &sy))
1188             goto onerr;
1189     }
1190
1191     parser->lex->flags.noops = true;
1192     if (!sy.out_count) {
1193         parseerror(parser, "empty expression");
1194         expr = NULL;
1195     } else
1196         expr = sy.out[0].out;
1197     MEM_VECTOR_CLEAR(&sy, out);
1198     MEM_VECTOR_CLEAR(&sy, ops);
1199     DEBUGSHUNTDO(printf("shunt done\n"));
1200     return expr;
1201
1202 onerr:
1203     parser->lex->flags.noops = true;
1204     MEM_VECTOR_CLEAR(&sy, out);
1205     MEM_VECTOR_CLEAR(&sy, ops);
1206     return NULL;
1207 }
1208
1209 static ast_expression* parser_expression(parser_t *parser, bool stopatcomma)
1210 {
1211     ast_expression *e = parser_expression_leave(parser, stopatcomma);
1212     if (!e)
1213         return NULL;
1214     if (!parser_next(parser)) {
1215         ast_delete(e);
1216         return NULL;
1217     }
1218     return e;
1219 }
1220
1221 static bool parser_parse_if(parser_t *parser, ast_block *block, ast_expression **out)
1222 {
1223     ast_ifthen *ifthen;
1224     ast_expression *cond, *ontrue, *onfalse = NULL;
1225
1226     lex_ctx ctx = parser_ctx(parser);
1227
1228     /* skip the 'if' and check for opening paren */
1229     if (!parser_next(parser) || parser->tok != '(') {
1230         parseerror(parser, "expected 'if' condition in parenthesis");
1231         return false;
1232     }
1233     /* parse into the expression */
1234     if (!parser_next(parser)) {
1235         parseerror(parser, "expected 'if' condition after opening paren");
1236         return false;
1237     }
1238     /* parse the condition */
1239     cond = parser_expression_leave(parser, false);
1240     if (!cond)
1241         return false;
1242     /* closing paren */
1243     if (parser->tok != ')') {
1244         parseerror(parser, "expected closing paren after 'if' condition");
1245         ast_delete(cond);
1246         return false;
1247     }
1248     /* parse into the 'then' branch */
1249     if (!parser_next(parser)) {
1250         parseerror(parser, "expected statement for on-true branch of 'if'");
1251         ast_delete(cond);
1252         return false;
1253     }
1254     ontrue = parser_parse_statement_or_block(parser);
1255     if (!ontrue) {
1256         ast_delete(cond);
1257         return false;
1258     }
1259     /* check for an else */
1260     if (!strcmp(parser_tokval(parser), "else")) {
1261         /* parse into the 'else' branch */
1262         if (!parser_next(parser)) {
1263             parseerror(parser, "expected on-false branch after 'else'");
1264             ast_delete(ontrue);
1265             ast_delete(cond);
1266             return false;
1267         }
1268         onfalse = parser_parse_statement_or_block(parser);
1269         if (!onfalse) {
1270             ast_delete(ontrue);
1271             ast_delete(cond);
1272             return false;
1273         }
1274     }
1275
1276     ifthen = ast_ifthen_new(ctx, cond, ontrue, onfalse);
1277     *out = (ast_expression*)ifthen;
1278     return true;
1279 }
1280
1281 static bool parser_parse_while(parser_t *parser, ast_block *block, ast_expression **out)
1282 {
1283     ast_loop *aloop;
1284     ast_expression *cond, *ontrue;
1285
1286     lex_ctx ctx = parser_ctx(parser);
1287
1288     /* skip the 'while' and check for opening paren */
1289     if (!parser_next(parser) || parser->tok != '(') {
1290         parseerror(parser, "expected 'while' condition in parenthesis");
1291         return false;
1292     }
1293     /* parse into the expression */
1294     if (!parser_next(parser)) {
1295         parseerror(parser, "expected 'while' condition after opening paren");
1296         return false;
1297     }
1298     /* parse the condition */
1299     cond = parser_expression_leave(parser, false);
1300     if (!cond)
1301         return false;
1302     /* closing paren */
1303     if (parser->tok != ')') {
1304         parseerror(parser, "expected closing paren after 'while' condition");
1305         ast_delete(cond);
1306         return false;
1307     }
1308     /* parse into the 'then' branch */
1309     if (!parser_next(parser)) {
1310         parseerror(parser, "expected while-loop body");
1311         ast_delete(cond);
1312         return false;
1313     }
1314     ontrue = parser_parse_statement_or_block(parser);
1315     if (!ontrue) {
1316         ast_delete(cond);
1317         return false;
1318     }
1319
1320     aloop = ast_loop_new(ctx, NULL, cond, NULL, NULL, ontrue);
1321     *out = (ast_expression*)aloop;
1322     return true;
1323 }
1324
1325 static bool parser_parse_dowhile(parser_t *parser, ast_block *block, ast_expression **out)
1326 {
1327     ast_loop *aloop;
1328     ast_expression *cond, *ontrue;
1329
1330     lex_ctx ctx = parser_ctx(parser);
1331
1332     /* skip the 'do' and get the body */
1333     if (!parser_next(parser)) {
1334         parseerror(parser, "expected loop body");
1335         return false;
1336     }
1337     ontrue = parser_parse_statement_or_block(parser);
1338     if (!ontrue)
1339         return false;
1340
1341     /* expect the "while" */
1342     if (parser->tok != TOKEN_KEYWORD ||
1343         strcmp(parser_tokval(parser), "while"))
1344     {
1345         parseerror(parser, "expected 'while' and condition");
1346         ast_delete(ontrue);
1347         return false;
1348     }
1349
1350     /* skip the 'while' and check for opening paren */
1351     if (!parser_next(parser) || parser->tok != '(') {
1352         parseerror(parser, "expected 'while' condition in parenthesis");
1353         ast_delete(ontrue);
1354         return false;
1355     }
1356     /* parse into the expression */
1357     if (!parser_next(parser)) {
1358         parseerror(parser, "expected 'while' condition after opening paren");
1359         ast_delete(ontrue);
1360         return false;
1361     }
1362     /* parse the condition */
1363     cond = parser_expression_leave(parser, false);
1364     if (!cond)
1365         return false;
1366     /* closing paren */
1367     if (parser->tok != ')') {
1368         parseerror(parser, "expected closing paren after 'while' condition");
1369         ast_delete(ontrue);
1370         ast_delete(cond);
1371         return false;
1372     }
1373     /* parse on */
1374     if (!parser_next(parser) || parser->tok != ';') {
1375         parseerror(parser, "expected semicolon after condition");
1376         ast_delete(ontrue);
1377         ast_delete(cond);
1378         return false;
1379     }
1380
1381     if (!parser_next(parser)) {
1382         parseerror(parser, "parse error");
1383         ast_delete(ontrue);
1384         ast_delete(cond);
1385         return false;
1386     }
1387
1388     aloop = ast_loop_new(ctx, NULL, NULL, cond, NULL, ontrue);
1389     *out = (ast_expression*)aloop;
1390     return true;
1391 }
1392
1393 static bool parser_parse_for(parser_t *parser, ast_block *block, ast_expression **out)
1394 {
1395     ast_loop *aloop;
1396     ast_expression *initexpr, *cond, *increment, *ontrue;
1397     size_t oldblocklocal;
1398
1399     lex_ctx ctx = parser_ctx(parser);
1400
1401     oldblocklocal = parser->blocklocal;
1402     parser->blocklocal = parser->locals_count;
1403
1404     initexpr  = NULL;
1405     cond      = NULL;
1406     increment = NULL;
1407     ontrue    = NULL;
1408
1409     /* skip the 'while' and check for opening paren */
1410     if (!parser_next(parser) || parser->tok != '(') {
1411         parseerror(parser, "expected 'for' expressions in parenthesis");
1412         goto onerr;
1413     }
1414     /* parse into the expression */
1415     if (!parser_next(parser)) {
1416         parseerror(parser, "expected 'for' initializer after opening paren");
1417         goto onerr;
1418     }
1419
1420     if (parser->tok == TOKEN_TYPENAME) {
1421         if (opts_standard != COMPILER_GMQCC) {
1422             if (parsewarning(parser, WARN_EXTENSIONS,
1423                              "current standard does not allow variable declarations in for-loop initializers"))
1424                 goto onerr;
1425         }
1426
1427         parseerror(parser, "TODO: assignment of new variables to be non-const");
1428         goto onerr;
1429         if (!parser_variable(parser, block))
1430             goto onerr;
1431     }
1432     else if (parser->tok != ';')
1433     {
1434         initexpr = parser_expression_leave(parser, false);
1435         if (!initexpr)
1436             goto onerr;
1437     }
1438
1439     /* move on to condition */
1440     if (parser->tok != ';') {
1441         parseerror(parser, "expected semicolon after for-loop initializer");
1442         goto onerr;
1443     }
1444     if (!parser_next(parser)) {
1445         parseerror(parser, "expected for-loop condition");
1446         goto onerr;
1447     }
1448
1449     /* parse the condition */
1450     if (parser->tok != ';') {
1451         cond = parser_expression_leave(parser, false);
1452         if (!cond)
1453             goto onerr;
1454     }
1455
1456     /* move on to incrementor */
1457     if (parser->tok != ';') {
1458         parseerror(parser, "expected semicolon after for-loop initializer");
1459         goto onerr;
1460     }
1461     if (!parser_next(parser)) {
1462         parseerror(parser, "expected for-loop condition");
1463         goto onerr;
1464     }
1465
1466     /* parse the incrementor */
1467     if (parser->tok != ')') {
1468         increment = parser_expression_leave(parser, false);
1469         if (!increment)
1470             goto onerr;
1471     }
1472
1473     /* closing paren */
1474     if (parser->tok != ')') {
1475         parseerror(parser, "expected closing paren after 'for-loop' incrementor");
1476         goto onerr;
1477     }
1478     /* parse into the 'then' branch */
1479     if (!parser_next(parser)) {
1480         parseerror(parser, "expected for-loop body");
1481         goto onerr;
1482     }
1483     ontrue = parser_parse_statement_or_block(parser);
1484     if (!ontrue) {
1485         goto onerr;
1486     }
1487
1488     aloop = ast_loop_new(ctx, initexpr, cond, NULL, increment, ontrue);
1489     *out = (ast_expression*)aloop;
1490
1491     while (parser->locals_count > parser->blocklocal)
1492         parser_pop_local(parser);
1493     parser->blocklocal = oldblocklocal;
1494     return true;
1495 onerr:
1496     if (initexpr)  ast_delete(initexpr);
1497     if (cond)      ast_delete(cond);
1498     if (increment) ast_delete(increment);
1499     while (parser->locals_count > parser->blocklocal)
1500         parser_pop_local(parser);
1501     parser->blocklocal = oldblocklocal;
1502     return false;
1503 }
1504
1505 static bool parser_parse_statement(parser_t *parser, ast_block *block, ast_expression **out)
1506 {
1507     if (parser->tok == TOKEN_TYPENAME)
1508     {
1509         /* local variable */
1510         if (!block) {
1511             parseerror(parser, "cannot declare a variable from here");
1512             return false;
1513         }
1514         if (opts_standard == COMPILER_QCC) {
1515             if (parsewarning(parser, WARN_EXTENSIONS, "missing 'local' keyword when declaring a local variable"))
1516                 return false;
1517         }
1518         if (!parser_variable(parser, block))
1519             return false;
1520         *out = NULL;
1521         return true;
1522     }
1523     else if (parser->tok == TOKEN_KEYWORD)
1524     {
1525         if (!strcmp(parser_tokval(parser), "local"))
1526         {
1527             if (!block) {
1528                 parseerror(parser, "cannot declare a local variable here");
1529                 return false;
1530             }
1531             if (!parser_next(parser)) {
1532                 parseerror(parser, "expected variable declaration");
1533                 return false;
1534             }
1535             if (!parser_variable(parser, block))
1536                 return false;
1537             *out = NULL;
1538             return true;
1539         }
1540         else if (!strcmp(parser_tokval(parser), "return"))
1541         {
1542             ast_expression *exp = NULL;
1543             ast_return     *ret = NULL;
1544             ast_value      *expected = parser->function->vtype;
1545
1546             if (!parser_next(parser)) {
1547                 parseerror(parser, "expected return expression");
1548                 return false;
1549             }
1550
1551             if (parser->tok != ';') {
1552                 exp = parser_expression(parser, false);
1553                 if (!exp)
1554                     return false;
1555
1556                 if (exp->expression.vtype != expected->expression.next->expression.vtype) {
1557                     parseerror(parser, "return with invalid expression");
1558                 }
1559
1560                 ret = ast_return_new(exp->expression.node.context, exp);
1561                 if (!ret) {
1562                     ast_delete(exp);
1563                     return false;
1564                 }
1565
1566                 *out = (ast_expression*)ret;
1567             } else if (!parser_next(parser)) {
1568                 parseerror(parser, "expected semicolon");
1569                 if (expected->expression.next->expression.vtype != TYPE_VOID) {
1570                     parseerror(parser, "return without value");
1571                 }
1572             }
1573             return true;
1574         }
1575         else if (!strcmp(parser_tokval(parser), "if"))
1576         {
1577             return parser_parse_if(parser, block, out);
1578         }
1579         else if (!strcmp(parser_tokval(parser), "while"))
1580         {
1581             return parser_parse_while(parser, block, out);
1582         }
1583         else if (!strcmp(parser_tokval(parser), "do"))
1584         {
1585             return parser_parse_dowhile(parser, block, out);
1586         }
1587         else if (!strcmp(parser_tokval(parser), "for"))
1588         {
1589             if (opts_standard == COMPILER_QCC) {
1590                 if (parsewarning(parser, WARN_EXTENSIONS, "for loops are not recognized in the original Quake C standard, to enable try an alternate standard --std=?"))
1591                     return false;
1592             }
1593             return parser_parse_for(parser, block, out);
1594         }
1595         parseerror(parser, "Unexpected keyword");
1596         return false;
1597     }
1598     else if (parser->tok == '{')
1599     {
1600         ast_block *inner;
1601         inner = parser_parse_block(parser);
1602         if (!inner)
1603             return false;
1604         *out = (ast_expression*)inner;
1605         return true;
1606     }
1607     else
1608     {
1609         ast_expression *exp = parser_expression(parser, false);
1610         if (!exp)
1611             return false;
1612         *out = exp;
1613         return true;
1614     }
1615 }
1616
1617 static void parser_pop_local(parser_t *parser)
1618 {
1619     parser->locals_count--;
1620     mem_d(parser->locals[parser->locals_count].name);
1621 }
1622
1623 static ast_block* parser_parse_block(parser_t *parser)
1624 {
1625     size_t oldblocklocal;
1626     ast_block *block = NULL;
1627
1628     oldblocklocal = parser->blocklocal;
1629     parser->blocklocal = parser->locals_count;
1630
1631     if (!parser_next(parser)) { /* skip the '{' */
1632         parseerror(parser, "expected function body");
1633         goto cleanup;
1634     }
1635
1636     block = ast_block_new(parser_ctx(parser));
1637
1638     while (parser->tok != TOKEN_EOF && parser->tok < TOKEN_ERROR)
1639     {
1640         ast_expression *expr;
1641         if (parser->tok == '}')
1642             break;
1643
1644         if (!parser_parse_statement(parser, block, &expr)) {
1645             ast_block_delete(block);
1646             block = NULL;
1647             goto cleanup;
1648         }
1649         if (!expr)
1650             continue;
1651         if (!ast_block_exprs_add(block, expr)) {
1652             ast_delete(expr);
1653             ast_block_delete(block);
1654             block = NULL;
1655             goto cleanup;
1656         }
1657     }
1658
1659     if (parser->tok != '}') {
1660         ast_block_delete(block);
1661         block = NULL;
1662     } else {
1663         (void)parser_next(parser);
1664     }
1665
1666 cleanup:
1667     while (parser->locals_count > parser->blocklocal)
1668         parser_pop_local(parser);
1669     parser->blocklocal = oldblocklocal;
1670     /* unroll the local vector */
1671     return block;
1672 }
1673
1674 static ast_expression* parser_parse_statement_or_block(parser_t *parser)
1675 {
1676     ast_expression *expr;
1677     if (parser->tok == '{')
1678         return (ast_expression*)parser_parse_block(parser);
1679     if (!parser_parse_statement(parser, NULL, &expr))
1680         return NULL;
1681     return expr;
1682 }
1683
1684 static bool parser_variable(parser_t *parser, ast_block *localblock)
1685 {
1686     bool          isfunc = false;
1687     ast_function *func = NULL;
1688     lex_ctx       ctx;
1689     ast_value    *var;
1690     varentry_t    varent;
1691     ast_expression *olddecl;
1692
1693     int basetype = parser_token(parser)->constval.t;
1694
1695     while (true)
1696     {
1697         if (!parser_next(parser)) { /* skip basetype or comma */
1698             parseerror(parser, "expected variable declaration");
1699             return false;
1700         }
1701
1702         olddecl = NULL;
1703         isfunc  = false;
1704         func    = NULL;
1705         ctx = parser_ctx(parser);
1706         var = parser_parse_type(parser, basetype, &isfunc);
1707
1708         if (!var)
1709             return false;
1710
1711         if (parser->tok != TOKEN_IDENT) {
1712             parseerror(parser, "expected variable name\n");
1713             return false;
1714         }
1715
1716         if (!isfunc) {
1717             if (!localblock && (olddecl = parser_find_global(parser, parser_tokval(parser)))) {
1718                 ast_value_delete(var);
1719                 parseerror(parser, "global %s already declared here: %s:%i\n",
1720                            parser_tokval(parser), ast_ctx(olddecl).file, (int)ast_ctx(olddecl).line);
1721                 return false;
1722             }
1723
1724             if (localblock && parser_find_local(parser, parser_tokval(parser), parser->blocklocal)) {
1725                 ast_value_delete(var);
1726                 parseerror(parser, "local %s already declared here: %s:%i\n",
1727                            parser_tokval(parser), ast_ctx(olddecl).file, (int)ast_ctx(olddecl).line);
1728                 return false;
1729             }
1730         }
1731
1732         if (!ast_value_set_name(var, parser_tokval(parser))) {
1733             parseerror(parser, "failed to set variable name\n");
1734             ast_value_delete(var);
1735             return false;
1736         }
1737
1738         if (isfunc) {
1739             /* a function was defined */
1740             ast_value *fval;
1741             ast_value *proto = NULL;
1742
1743             if (!localblock)
1744                 olddecl = parser_find_global(parser, parser_tokval(parser));
1745             else
1746                 olddecl = parser_find_local(parser, parser_tokval(parser), parser->blocklocal);
1747
1748             if (olddecl) {
1749                 /* we had a prototype */
1750                 if (!ast_istype(olddecl, ast_value)) {
1751                     /* theoretically not possible you think?
1752                      * well:
1753                      * vector v;
1754                      * void() v_x = {}
1755                      * got it?
1756                      */
1757                     parseerror(parser, "cannot declare a function with the same name as a vector's member: %s",
1758                                parser_tokval(parser));
1759                     ast_value_delete(var);
1760                     return false;
1761                 }
1762
1763                 proto = (ast_value*)olddecl;
1764             }
1765
1766             /* turn var into a value of TYPE_FUNCTION, with the old var
1767              * as return type
1768              */
1769             fval = ast_value_new(ctx, var->name, TYPE_FUNCTION);
1770             func = ast_function_new(ctx, var->name, fval);
1771             if (!fval || !func) {
1772                 ast_value_delete(var);
1773                 if (fval) ast_value_delete(fval);
1774                 if (func) ast_function_delete(func);
1775                 return false;
1776             }
1777
1778             fval->expression.next = (ast_expression*)var;
1779             MEM_VECTOR_MOVE(&var->expression, params, &fval->expression, params);
1780
1781             /* we compare the type late here, but it's easier than
1782              * messing with the parameter-vector etc. earlier
1783              */
1784             if (proto) {
1785                 if (!ast_compare_type((ast_expression*)proto, (ast_expression*)fval)) {
1786                     parseerror(parser, "conflicting types for `%s`, previous declaration was here: %s:%i",
1787                                proto->name,
1788                                ast_ctx(proto).file, ast_ctx(proto).line);
1789                     ast_function_delete(func);
1790                     ast_value_delete(fval);
1791                     return false;
1792                 }
1793                 ast_function_delete(func);
1794                 ast_value_delete(fval);
1795                 var = proto;
1796                 func = var->constval.vfunc;
1797             }
1798             else
1799             {
1800                 if (!parser_t_functions_add(parser, func)) {
1801                     ast_function_delete(func);
1802                     ast_value_delete(fval);
1803                     return false;
1804                 }
1805             }
1806
1807             var = fval;
1808         }
1809
1810         varent.name = util_strdup(var->name);
1811         varent.var = (ast_expression*)var;
1812         if (var->expression.vtype == TYPE_VECTOR)
1813         {
1814             size_t len = strlen(varent.name);
1815             varentry_t vx, vy, vz;
1816             vx.var = (ast_expression*)ast_member_new(var->expression.node.context, (ast_expression*)var, 0);
1817             vy.var = (ast_expression*)ast_member_new(var->expression.node.context, (ast_expression*)var, 1);
1818             vz.var = (ast_expression*)ast_member_new(var->expression.node.context, (ast_expression*)var, 2);
1819             vx.name = (char*)mem_a(len+3);
1820             vy.name = (char*)mem_a(len+3);
1821             vz.name = (char*)mem_a(len+3);
1822             memcpy(vx.name, varent.name, len);
1823             memcpy(vy.name, varent.name, len);
1824             memcpy(vz.name, varent.name, len);
1825             vx.name[len] = vy.name[len] = vz.name[len] = '_';
1826             vx.name[len+1] = 'x';
1827             vy.name[len+1] = 'y';
1828             vz.name[len+1] = 'z';
1829             vx.name[len+2] = vy.name[len+2] = vz.name[len+2] = 0;
1830
1831             if (!localblock) {
1832                 (void)!parser_t_globals_add(parser, varent);
1833                 (void)!parser_t_globals_add(parser, vx);
1834                 (void)!parser_t_globals_add(parser, vy);
1835                 (void)!parser_t_globals_add(parser, vz);
1836             } else {
1837                 (void)!parser_t_locals_add(parser, varent);
1838                 (void)!parser_t_locals_add(parser, vx);
1839                 (void)!parser_t_locals_add(parser, vy);
1840                 (void)!parser_t_locals_add(parser, vz);
1841             }
1842         }
1843         else
1844         {
1845             if ( (!localblock && !parser_t_globals_add(parser, varent)) ||
1846                  ( localblock && !parser_t_locals_add(parser, varent)) )
1847             {
1848                 ast_value_delete(var);
1849                 return false;
1850             }
1851         }
1852         if (localblock && !ast_block_locals_add(localblock, var))
1853         {
1854             parser_pop_local(parser);
1855             ast_value_delete(var);
1856             return false;
1857         }
1858
1859         if (!parser_next(parser)) {
1860             ast_value_delete(var);
1861             return false;
1862         }
1863
1864         if (parser->tok == ';') {
1865             if (!parser_next(parser))
1866                 return parser->tok == TOKEN_EOF;
1867             return true;
1868         }
1869
1870         if (parser->tok == ',') {
1871             /* another var */
1872             continue;
1873         }
1874
1875         if (parser->tok != '=') {
1876             parseerror(parser, "expected '=' or ';'");
1877             return false;
1878         }
1879
1880         if (!parser_next(parser))
1881             return false;
1882
1883         if (parser->tok == '#') {
1884             if (localblock) {
1885                 parseerror(parser, "cannot declare builtins within functions");
1886                 return false;
1887             }
1888             if (!isfunc || !func) {
1889                 parseerror(parser, "unexpected builtin number, '%s' is not a function", var->name);
1890                 return false;
1891             }
1892             if (!parser_next(parser)) {
1893                 parseerror(parser, "expected builtin number");
1894                 return false;
1895             }
1896             if (parser->tok != TOKEN_INTCONST) {
1897                 parseerror(parser, "builtin number must be an integer constant");
1898                 return false;
1899             }
1900             if (parser_token(parser)->constval.i <= 0) {
1901                 parseerror(parser, "builtin number must be positive integer greater than zero");
1902                 return false;
1903             }
1904
1905             func->builtin = -parser_token(parser)->constval.i;
1906
1907             if (!parser_next(parser))
1908                 return false;
1909         } else if (parser->tok == '{') {
1910             /* function body */
1911             ast_block *block;
1912             ast_function *old = parser->function;
1913
1914             if (localblock) {
1915                 parseerror(parser, "cannot declare functions within functions");
1916                 return false;
1917             }
1918
1919             parser->function = func;
1920             block = parser_parse_block(parser);
1921             parser->function = old;
1922
1923             if (!block)
1924                 return false;
1925
1926             if (!ast_function_blocks_add(func, block)) {
1927                 ast_block_delete(block);
1928                 return false;
1929             }
1930
1931             if (parser->tok == ';')
1932                 return parser_next(parser) || parser->tok == TOKEN_EOF;
1933             else if (opts_standard == COMPILER_QCC)
1934                 parseerror(parser, "missing semicolon after function body (mandatory with -std=qcc)");
1935             return true;
1936         } else {
1937             ast_expression *cexp;
1938             ast_value      *cval;
1939
1940             cexp = parser_expression_leave(parser, true);
1941             cval = (ast_value*)cexp;
1942             if (!ast_istype(cval, ast_value) || !cval->isconst)
1943                 parseerror(parser, "cannot initialize a global constant variable with a non-constant expression");
1944             else
1945             {
1946                 var->isconst = true;
1947                 memcpy(&var->constval, &cval->constval, sizeof(var->constval));
1948                 memset(&cval->constval, 0, sizeof(cval->constval));
1949                 ast_unref(cval);
1950             }
1951         }
1952
1953         if (parser->tok == ',') {
1954             /* another */
1955             continue;
1956         }
1957
1958         if (parser->tok != ';') {
1959             parseerror(parser, "missing semicolon");
1960             return false;
1961         }
1962
1963         (void)parser_next(parser);
1964
1965         return true;
1966     }
1967 }
1968
1969 static bool parser_do(parser_t *parser)
1970 {
1971     if (parser->tok == TOKEN_TYPENAME)
1972     {
1973         return parser_variable(parser, NULL);
1974     }
1975     else if (parser->tok == TOKEN_KEYWORD)
1976     {
1977         /* handle 'var' and 'const' */
1978         return false;
1979     }
1980     else if (parser->tok == '.')
1981     {
1982         ast_value *var;
1983         ast_value *fld;
1984         ast_expression *oldex;
1985         bool       isfunc = false;
1986         int        basetype;
1987         lex_ctx    ctx = parser_ctx(parser);
1988         varentry_t varent;
1989
1990         /* entity-member declaration */
1991         if (!parser_next(parser) || parser->tok != TOKEN_TYPENAME) {
1992             parseerror(parser, "expected member variable definition");
1993             return false;
1994         }
1995
1996         /* remember the base/return type */
1997         basetype = parser_token(parser)->constval.t;
1998
1999         /* parse into the declaration */
2000         if (!parser_next(parser)) {
2001             parseerror(parser, "expected field def");
2002             return false;
2003         }
2004
2005         /* parse the field type fully */
2006         var = parser_parse_type(parser, basetype, &isfunc);
2007         if (!var)
2008             return false;
2009
2010         while (true) {
2011             /* now the field name */
2012             if (parser->tok != TOKEN_IDENT) {
2013                 parseerror(parser, "expected field name");
2014                 ast_delete(var);
2015                 return false;
2016             }
2017
2018             /* check for an existing field
2019              * in original qc we also have to check for an existing
2020              * global named like the field
2021              */
2022             if (opts_standard == COMPILER_QCC) {
2023                 if (parser_find_global(parser, parser_tokval(parser))) {
2024                     parseerror(parser, "cannot declare a field and a global of the same name with -std=qcc");
2025                     ast_delete(var);
2026                     return false;
2027                 }
2028             }
2029
2030             if (isfunc) {
2031                 ast_value *fval;
2032                 fval = ast_value_new(ctx, var->name, TYPE_FUNCTION);
2033                 if (!fval) {
2034                     ast_value_delete(var);
2035                     return false;
2036                 }
2037                 fval->expression.next = (ast_expression*)var;
2038                 MEM_VECTOR_MOVE(&var->expression, params, &fval->expression, params);
2039                 var = fval;
2040             }
2041
2042             /* turn it into a field */
2043             fld = ast_value_new(ctx, parser_tokval(parser), TYPE_FIELD);
2044             fld->expression.next = (ast_expression*)var;
2045
2046             if ( (oldex = parser_find_field(parser, parser_tokval(parser)))) {
2047                 if (ast_istype(oldex, ast_member)) {
2048                     parseerror(parser, "cannot declare a field with the same name as a vector component, component %s has been declared here: %s:%i",
2049                                parser_tokval(parser), ast_ctx(oldex).file, (int)ast_ctx(oldex).line);
2050                     ast_delete(fld);
2051                     return false;
2052                 }
2053                 if (!ast_istype(oldex, ast_value)) {
2054                     /* not possible / sanity check */
2055                     parseerror(parser, "internal error: %s is not an ast_value", parser_tokval(parser));
2056                     ast_delete(fld);
2057                     return false;
2058                 }
2059
2060                 if (!ast_compare_type(oldex, (ast_expression*)fld)) {
2061                     parseerror(parser, "field %s has previously been declared with a different type here: %s:%i",
2062                                parser_tokval(parser), ast_ctx(oldex).file, (int)ast_ctx(oldex).line);
2063                     ast_delete(fld);
2064                     return false;
2065                 } else {
2066                     if (parsewarning(parser, WARN_FIELD_REDECLARED, "field %s has already been declared here: %s:%i",
2067                                      parser_tokval(parser), ast_ctx(oldex).file, (int)ast_ctx(oldex).line))
2068                     {
2069                         ast_delete(fld);
2070                         return false;
2071                     }
2072                 }
2073
2074                 ast_delete(fld);
2075                 goto nextfield;
2076             }
2077
2078             varent.var = (ast_expression*)fld;
2079             varent.name = util_strdup(fld->name);
2080             (void)!parser_t_fields_add(parser, varent);
2081
2082             if (var->expression.vtype == TYPE_VECTOR)
2083             {
2084                 /* create _x, _y and _z fields as well */
2085                 size_t len;
2086                 varentry_t vx, vy, vz;
2087
2088                 len = strlen(varent.name);
2089                 vx.var = (ast_expression*)ast_member_new(ast_ctx(fld), (ast_expression*)fld, 0);
2090                 vy.var = (ast_expression*)ast_member_new(ast_ctx(fld), (ast_expression*)fld, 1);
2091                 vz.var = (ast_expression*)ast_member_new(ast_ctx(fld), (ast_expression*)fld, 2);
2092                 vx.name = (char*)mem_a(len+3);
2093                 vy.name = (char*)mem_a(len+3);
2094                 vz.name = (char*)mem_a(len+3);
2095                 memcpy(vx.name, varent.name, len);
2096                 memcpy(vy.name, varent.name, len);
2097                 memcpy(vz.name, varent.name, len);
2098                 vx.name[len] = vy.name[len] = vz.name[len] = '_';
2099                 vx.name[len+1] = 'x';
2100                 vy.name[len+1] = 'y';
2101                 vz.name[len+1] = 'z';
2102                 vx.name[len+2] = vy.name[len+2] = vz.name[len+2] = 0;
2103                 (void)!parser_t_fields_add(parser, vx);
2104                 (void)!parser_t_fields_add(parser, vy);
2105                 (void)!parser_t_fields_add(parser, vz);
2106             }
2107
2108 nextfield:
2109             if (!parser_next(parser)) {
2110                 parseerror(parser, "expected semicolon or another field name");
2111                 return false;
2112             }
2113             if (parser->tok == ';')
2114                 break;
2115             if (parser->tok != ',' || !parser_next(parser)) {
2116                 parseerror(parser, "expected semicolon or another field name");
2117                 return false;
2118             }
2119         }
2120
2121         /* skip the semicolon */
2122         if (!parser_next(parser))
2123             return parser->tok == TOKEN_EOF;
2124
2125         return true;
2126     }
2127     else
2128     {
2129         parseerror(parser, "unexpected token: %s", parser->lex->tok->value);
2130         return false;
2131     }
2132     return true;
2133 }
2134
2135 static parser_t *parser;
2136
2137 bool parser_init()
2138 {
2139     parser = (parser_t*)mem_a(sizeof(parser_t));
2140     if (!parser)
2141         return false;
2142
2143     memset(parser, 0, sizeof(*parser));
2144     return true;
2145 }
2146
2147 bool parser_compile(const char *filename)
2148 {
2149     parser->lex = lex_open(filename);
2150     if (!parser->lex) {
2151         printf("failed to open file \"%s\"\n", filename);
2152         return false;
2153     }
2154
2155     /* initial lexer/parser state */
2156     parser->lex->flags.noops = true;
2157
2158     if (parser_next(parser))
2159     {
2160         while (parser->tok != TOKEN_EOF && parser->tok < TOKEN_ERROR)
2161         {
2162             if (!parser_do(parser)) {
2163                 if (parser->tok == TOKEN_EOF)
2164                     parseerror(parser, "unexpected eof");
2165                 else if (!parser->errors)
2166                     parseerror(parser, "parse error\n");
2167                 lex_close(parser->lex);
2168                 mem_d(parser);
2169                 return false;
2170             }
2171         }
2172     }
2173
2174     lex_close(parser->lex);
2175
2176     return !parser->errors;
2177 }
2178
2179 void parser_cleanup()
2180 {
2181     size_t i;
2182     for (i = 0; i < parser->functions_count; ++i) {
2183         ast_delete(parser->functions[i]);
2184     }
2185     for (i = 0; i < parser->imm_vector_count; ++i) {
2186         ast_delete(parser->imm_vector[i]);
2187     }
2188     for (i = 0; i < parser->imm_string_count; ++i) {
2189         ast_delete(parser->imm_string[i]);
2190     }
2191     for (i = 0; i < parser->imm_float_count; ++i) {
2192         ast_delete(parser->imm_float[i]);
2193     }
2194     for (i = 0; i < parser->globals_count; ++i) {
2195         ast_delete(parser->globals[i].var);
2196         mem_d(parser->globals[i].name);
2197     }
2198     MEM_VECTOR_CLEAR(parser, globals);
2199
2200     mem_d(parser);
2201 }
2202
2203 bool parser_finish(const char *output)
2204 {
2205     size_t i;
2206     ir_builder *ir;
2207
2208     if (!parser->errors)
2209     {
2210         ir = ir_builder_new("gmqcc_out");
2211         if (!ir) {
2212             printf("failed to allocate builder\n");
2213             return false;
2214         }
2215
2216         for (i = 0; i < parser->imm_float_count; ++i) {
2217             if (!ast_global_codegen(parser->imm_float[i], ir)) {
2218                 printf("failed to generate global %s\n", parser->imm_float[i]->name);
2219                 ir_builder_delete(ir);
2220                 return false;
2221             }
2222         }
2223         for (i = 0; i < parser->imm_string_count; ++i) {
2224             if (!ast_global_codegen(parser->imm_string[i], ir)) {
2225                 printf("failed to generate global %s\n", parser->imm_string[i]->name);
2226                 ir_builder_delete(ir);
2227                 return false;
2228             }
2229         }
2230         for (i = 0; i < parser->imm_vector_count; ++i) {
2231             if (!ast_global_codegen(parser->imm_vector[i], ir)) {
2232                 printf("failed to generate global %s\n", parser->imm_vector[i]->name);
2233                 ir_builder_delete(ir);
2234                 return false;
2235             }
2236         }
2237         for (i = 0; i < parser->fields_count; ++i) {
2238             ast_value *field;
2239             bool isconst;
2240             if (!ast_istype(parser->fields[i].var, ast_value))
2241                 continue;
2242             field = (ast_value*)parser->fields[i].var;
2243             isconst = field->isconst;
2244             field->isconst = false;
2245             if (!ast_global_codegen((ast_value*)field, ir)) {
2246                 printf("failed to generate field %s\n", field->name);
2247                 ir_builder_delete(ir);
2248                 return false;
2249             }
2250             if (isconst) {
2251                 ir_value *ifld;
2252                 ast_expression *subtype;
2253                 field->isconst = true;
2254                 subtype = field->expression.next;
2255                 ifld = ir_builder_create_field(ir, field->name, subtype->expression.vtype);
2256                 if (subtype->expression.vtype == TYPE_FIELD)
2257                     ifld->fieldtype = subtype->expression.next->expression.vtype;
2258                 else if (subtype->expression.vtype == TYPE_FUNCTION)
2259                     ifld->outtype = subtype->expression.next->expression.vtype;
2260                 (void)!ir_value_set_field(field->ir_v, ifld);
2261             }
2262         }
2263         for (i = 0; i < parser->globals_count; ++i) {
2264             if (!ast_istype(parser->globals[i].var, ast_value))
2265                 continue;
2266             if (!ast_global_codegen((ast_value*)(parser->globals[i].var), ir)) {
2267                 printf("failed to generate global %s\n", parser->globals[i].name);
2268                 ir_builder_delete(ir);
2269                 return false;
2270             }
2271         }
2272         for (i = 0; i < parser->functions_count; ++i) {
2273             if (!ast_function_codegen(parser->functions[i], ir)) {
2274                 printf("failed to generate function %s\n", parser->functions[i]->name);
2275                 ir_builder_delete(ir);
2276                 return false;
2277             }
2278             if (!ir_function_finalize(parser->functions[i]->ir_func)) {
2279                 printf("failed to finalize function %s\n", parser->functions[i]->name);
2280                 ir_builder_delete(ir);
2281                 return false;
2282             }
2283         }
2284
2285         if (opts_dump)
2286             ir_builder_dump(ir, printf);
2287
2288         if (!ir_builder_generate(ir, output)) {
2289             printf("*** failed to generate output file\n");
2290             ir_builder_delete(ir);
2291             return false;
2292         }
2293
2294         ir_builder_delete(ir);
2295         return true;
2296     }
2297
2298     printf("*** there were compile errors\n");
2299     return false;
2300 }