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