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