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