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