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