renaming some ast_node members before making ast_expression an ast_node to use the...
[xonotic/gmqcc.git] / parser.cpp
1 #include <string.h>
2 #include <math.h>
3
4 #include "intrin.h"
5 #include "fold.h"
6 #include "ast.h"
7 #include "parser.h"
8
9 #define PARSER_HT_LOCALS  2
10 #define PARSER_HT_SIZE    512
11 #define TYPEDEF_HT_SIZE   512
12
13 static void parser_enterblock(parser_t *parser);
14 static bool parser_leaveblock(parser_t *parser);
15 static void parser_addlocal(parser_t *parser, const char *name, ast_expression *e);
16 static void parser_addglobal(parser_t *parser, const char *name, ast_expression *e);
17 static bool parse_typedef(parser_t *parser);
18 static bool parse_variable(parser_t *parser, ast_block *localblock, bool nofields, int qualifier, ast_value *cached_typedef, bool noref, bool is_static, uint32_t qflags, char *vstring);
19 static ast_block* parse_block(parser_t *parser);
20 static bool parse_block_into(parser_t *parser, ast_block *block);
21 static bool parse_statement_or_block(parser_t *parser, ast_expression **out);
22 static bool parse_statement(parser_t *parser, ast_block *block, ast_expression **out, bool allow_cases);
23 static ast_expression* parse_expression_leave(parser_t *parser, bool stopatcomma, bool truthvalue, bool with_labels);
24 static ast_expression* parse_expression(parser_t *parser, bool stopatcomma, bool with_labels);
25 static ast_value* parser_create_array_setter_proto(parser_t *parser, ast_value *array, const char *funcname);
26 static ast_value* parser_create_array_getter_proto(parser_t *parser, ast_value *array, const ast_expression *elemtype, const char *funcname);
27 static ast_value *parse_typename(parser_t *parser, ast_value **storebase, ast_value *cached_typedef, bool *is_vararg);
28
29 static void parseerror(parser_t *parser, const char *fmt, ...)
30 {
31     va_list ap;
32     va_start(ap, fmt);
33     vcompile_error(parser->lex->tok.ctx, fmt, ap);
34     va_end(ap);
35 }
36
37 /* returns true if it counts as an error */
38 static bool GMQCC_WARN parsewarning(parser_t *parser, int warntype, const char *fmt, ...)
39 {
40     bool    r;
41     va_list ap;
42     va_start(ap, fmt);
43     r = vcompile_warning(parser->lex->tok.ctx, warntype, fmt, ap);
44     va_end(ap);
45     return r;
46 }
47
48 /**********************************************************************
49  * parsing
50  */
51
52 static bool parser_next(parser_t *parser)
53 {
54     /* lex_do kills the previous token */
55     parser->tok = lex_do(parser->lex);
56     if (parser->tok == TOKEN_EOF)
57         return true;
58     if (parser->tok >= TOKEN_ERROR) {
59         parseerror(parser, "lex error");
60         return false;
61     }
62     return true;
63 }
64
65 #define parser_tokval(p) ((p)->lex->tok.value)
66 #define parser_token(p)  (&((p)->lex->tok))
67
68 char *parser_strdup(const char *str)
69 {
70     if (str && !*str) {
71         /* actually dup empty strings */
72         char *out = (char*)mem_a(1);
73         *out = 0;
74         return out;
75     }
76     return util_strdup(str);
77 }
78
79 static ast_expression* parser_find_field(parser_t *parser, const char *name)
80 {
81     return ( ast_expression*)util_htget(parser->htfields, name);
82 }
83
84 static ast_expression* parser_find_label(parser_t *parser, const char *name)
85 {
86     for (auto &it : parser->labels)
87         if (!strcmp(it->name, name))
88             return (ast_expression*)it;
89     return nullptr;
90 }
91
92 ast_expression* parser_find_global(parser_t *parser, const char *name)
93 {
94     ast_expression *var = (ast_expression*)util_htget(parser->aliases, parser_tokval(parser));
95     if (var)
96         return var;
97     return (ast_expression*)util_htget(parser->htglobals, name);
98 }
99
100 static ast_expression* parser_find_param(parser_t *parser, const char *name)
101 {
102     ast_value *fun;
103     if (!parser->function)
104         return nullptr;
105     fun = parser->function->vtype;
106     for (auto &it : fun->expression.params) {
107         if (!strcmp(it->name, name))
108             return (ast_expression*)it;
109     }
110     return nullptr;
111 }
112
113 static ast_expression* parser_find_local(parser_t *parser, const char *name, size_t upto, bool *isparam)
114 {
115     size_t          i, hash;
116     ast_expression *e;
117
118     hash = util_hthash(parser->htglobals, name);
119
120     *isparam = false;
121     for (i = vec_size(parser->variables); i > upto;) {
122         --i;
123         if ( (e = (ast_expression*)util_htgeth(parser->variables[i], name, hash)) )
124             return e;
125     }
126     *isparam = true;
127     return parser_find_param(parser, name);
128 }
129
130 static ast_expression* parser_find_var(parser_t *parser, const char *name)
131 {
132     bool dummy;
133     ast_expression *v;
134     v         = parser_find_local(parser, name, 0, &dummy);
135     if (!v) v = parser_find_global(parser, name);
136     return v;
137 }
138
139 static ast_value* parser_find_typedef(parser_t *parser, const char *name, size_t upto)
140 {
141     size_t     i, hash;
142     ast_value *e;
143     hash = util_hthash(parser->typedefs[0], name);
144
145     for (i = vec_size(parser->typedefs); i > upto;) {
146         --i;
147         if ( (e = (ast_value*)util_htgeth(parser->typedefs[i], name, hash)) )
148             return e;
149     }
150     return nullptr;
151 }
152
153 struct sy_elem {
154     size_t etype; /* 0 = expression, others are operators */
155     bool isparen;
156     size_t off;
157     ast_expression *out;
158     ast_block *block; /* for commas and function calls */
159     lex_ctx_t ctx;
160 };
161
162 enum {
163     PAREN_EXPR,
164     PAREN_FUNC,
165     PAREN_INDEX,
166     PAREN_TERNARY1,
167     PAREN_TERNARY2
168 };
169
170 struct shunt {
171     std::vector<sy_elem> out;
172     std::vector<sy_elem> ops;
173     std::vector<size_t> argc;
174     std::vector<unsigned int> paren;
175 };
176
177 static sy_elem syexp(lex_ctx_t ctx, ast_expression *v) {
178     sy_elem e;
179     e.etype = 0;
180     e.off   = 0;
181     e.out   = v;
182     e.block = nullptr;
183     e.ctx   = ctx;
184     e.isparen = false;
185     return e;
186 }
187
188 static sy_elem syblock(lex_ctx_t ctx, ast_block *v) {
189     sy_elem e;
190     e.etype = 0;
191     e.off   = 0;
192     e.out   = (ast_expression*)v;
193     e.block = v;
194     e.ctx   = ctx;
195     e.isparen = false;
196     return e;
197 }
198
199 static sy_elem syop(lex_ctx_t ctx, const oper_info *op) {
200     sy_elem e;
201     e.etype = 1 + (op - operators);
202     e.off   = 0;
203     e.out   = nullptr;
204     e.block = nullptr;
205     e.ctx   = ctx;
206     e.isparen = false;
207     return e;
208 }
209
210 static sy_elem syparen(lex_ctx_t ctx, size_t off) {
211     sy_elem e;
212     e.etype = 0;
213     e.off   = off;
214     e.out   = nullptr;
215     e.block = nullptr;
216     e.ctx   = ctx;
217     e.isparen = true;
218     return e;
219 }
220
221 /* With regular precedence rules, ent.foo[n] is the same as (ent.foo)[n],
222  * so we need to rotate it to become ent.(foo[n]).
223  */
224 static bool rotate_entfield_array_index_nodes(ast_expression **out)
225 {
226     ast_array_index *index, *oldindex;
227     ast_entfield    *entfield;
228
229     ast_value       *field;
230     ast_expression  *sub;
231     ast_expression  *entity;
232
233     lex_ctx_t ctx = ast_ctx(*out);
234
235     if (!ast_istype(*out, ast_array_index))
236         return false;
237     index = (ast_array_index*)*out;
238
239     if (!ast_istype(index->array, ast_entfield))
240         return false;
241     entfield = (ast_entfield*)index->array;
242
243     if (!ast_istype(entfield->field, ast_value))
244         return false;
245     field = (ast_value*)entfield->field;
246
247     sub    = index->index;
248     entity = entfield->entity;
249
250     oldindex = index;
251
252     index = ast_array_index_new(ctx, (ast_expression*)field, sub);
253     entfield = ast_entfield_new(ctx, entity, (ast_expression*)index);
254     *out = (ast_expression*)entfield;
255
256     oldindex->array = nullptr;
257     oldindex->index = nullptr;
258     ast_delete(oldindex);
259
260     return true;
261 }
262
263 static bool check_write_to(lex_ctx_t ctx, ast_expression *expr)
264 {
265     if (ast_istype(expr, ast_value)) {
266         ast_value *val = (ast_value*)expr;
267         if (val->cvq == CV_CONST) {
268             if (val->name[0] == '#') {
269                 compile_error(ctx, "invalid assignment to a literal constant");
270                 return false;
271             }
272             /*
273              * To work around quakeworld we must elide the error and make it
274              * a warning instead.
275              */
276             if (OPTS_OPTION_U32(OPTION_STANDARD) != COMPILER_QCC)
277                 compile_error(ctx, "assignment to constant `%s`", val->name);
278             else
279                 (void)!compile_warning(ctx, WARN_CONST_OVERWRITE, "assignment to constant `%s`", val->name);
280             return false;
281         }
282     }
283     return true;
284 }
285
286 static bool parser_sy_apply_operator(parser_t *parser, shunt *sy)
287 {
288     const oper_info *op;
289     lex_ctx_t ctx;
290     ast_expression *out = nullptr;
291     ast_expression *exprs[3];
292     ast_block      *blocks[3];
293     ast_binstore   *asbinstore;
294     size_t i, assignop, addop, subop;
295     qcint_t  generated_op = 0;
296
297     char ty1[1024];
298     char ty2[1024];
299
300     if (sy->ops.empty()) {
301         parseerror(parser, "internal error: missing operator");
302         return false;
303     }
304
305     if (sy->ops.back().isparen) {
306         parseerror(parser, "unmatched parenthesis");
307         return false;
308     }
309
310     op = &operators[sy->ops.back().etype - 1];
311     ctx = sy->ops.back().ctx;
312
313     if (sy->out.size() < op->operands) {
314         if (op->flags & OP_PREFIX)
315             compile_error(ctx, "expected expression after unary operator `%s`", op->op, (int)op->id);
316         else /* this should have errored previously already */
317             compile_error(ctx, "expected expression after operator `%s`", op->op, (int)op->id);
318         return false;
319     }
320
321     sy->ops.pop_back();
322
323     /* op(:?) has no input and no output */
324     if (!op->operands)
325         return true;
326
327     sy->out.erase(sy->out.end() - op->operands, sy->out.end());
328     for (i = 0; i < op->operands; ++i) {
329         exprs[i]  = sy->out[sy->out.size()+i].out;
330         blocks[i] = sy->out[sy->out.size()+i].block;
331
332         if (exprs[i]->vtype == TYPE_NOEXPR &&
333             !(i != 0 && op->id == opid2('?',':')) &&
334             !(i == 1 && op->id == opid1('.')))
335         {
336             if (ast_istype(exprs[i], ast_label))
337                 compile_error(ast_ctx(exprs[i]), "expected expression, got an unknown identifier");
338             else
339                 compile_error(ast_ctx(exprs[i]), "not an expression");
340             (void)!compile_warning(ast_ctx(exprs[i]), WARN_DEBUG, "expression %u\n", (unsigned int)i);
341         }
342     }
343
344     if (blocks[0] && blocks[0]->exprs.empty() && op->id != opid1(',')) {
345         compile_error(ctx, "internal error: operator cannot be applied on empty blocks");
346         return false;
347     }
348
349 #define NotSameType(T) \
350              (exprs[0]->vtype != exprs[1]->vtype || \
351               exprs[0]->vtype != T)
352
353     switch (op->id)
354     {
355         default:
356             compile_error(ctx, "internal error: unhandled operator: %s (%i)", op->op, (int)op->id);
357             return false;
358
359         case opid1('.'):
360             if (exprs[0]->vtype == TYPE_VECTOR &&
361                 exprs[1]->vtype == TYPE_NOEXPR)
362             {
363                 if      (exprs[1] == (ast_expression*)parser->const_vec[0])
364                     out = (ast_expression*)ast_member_new(ctx, exprs[0], 0, nullptr);
365                 else if (exprs[1] == (ast_expression*)parser->const_vec[1])
366                     out = (ast_expression*)ast_member_new(ctx, exprs[0], 1, nullptr);
367                 else if (exprs[1] == (ast_expression*)parser->const_vec[2])
368                     out = (ast_expression*)ast_member_new(ctx, exprs[0], 2, nullptr);
369                 else {
370                     compile_error(ctx, "access to invalid vector component");
371                     return false;
372                 }
373             }
374             else if (exprs[0]->vtype == TYPE_ENTITY) {
375                 if (exprs[1]->vtype != TYPE_FIELD) {
376                     compile_error(ast_ctx(exprs[1]), "type error: right hand of member-operand should be an entity-field");
377                     return false;
378                 }
379                 out = (ast_expression*)ast_entfield_new(ctx, exprs[0], exprs[1]);
380             }
381             else if (exprs[0]->vtype == TYPE_VECTOR) {
382                 compile_error(ast_ctx(exprs[1]), "vectors cannot be accessed this way");
383                 return false;
384             }
385             else {
386                 compile_error(ast_ctx(exprs[1]), "type error: member-of operator on something that is not an entity or vector");
387                 return false;
388             }
389             break;
390
391         case opid1('['):
392             if (exprs[0]->vtype != TYPE_ARRAY &&
393                 !(exprs[0]->vtype == TYPE_FIELD &&
394                   exprs[0]->next->vtype == TYPE_ARRAY))
395             {
396                 ast_type_to_string(exprs[0], ty1, sizeof(ty1));
397                 compile_error(ast_ctx(exprs[0]), "cannot index value of type %s", ty1);
398                 return false;
399             }
400             if (exprs[1]->vtype != TYPE_FLOAT) {
401                 ast_type_to_string(exprs[0], ty1, sizeof(ty1));
402                 compile_error(ast_ctx(exprs[1]), "index must be of type float, not %s", ty1);
403                 return false;
404             }
405             out = (ast_expression*)ast_array_index_new(ctx, exprs[0], exprs[1]);
406             rotate_entfield_array_index_nodes(&out);
407             break;
408
409         case opid1(','):
410             if (sy->paren.size() && sy->paren.back() == PAREN_FUNC) {
411                 sy->out.push_back(syexp(ctx, exprs[0]));
412                 sy->out.push_back(syexp(ctx, exprs[1]));
413                 sy->argc.back()++;
414                 return true;
415             }
416             if (blocks[0]) {
417                 if (!ast_block_add_expr(blocks[0], exprs[1]))
418                     return false;
419             } else {
420                 blocks[0] = ast_block_new(ctx);
421                 if (!ast_block_add_expr(blocks[0], exprs[0]) ||
422                     !ast_block_add_expr(blocks[0], exprs[1]))
423                 {
424                     return false;
425                 }
426             }
427             ast_block_set_type(blocks[0], exprs[1]);
428
429             sy->out.push_back(syblock(ctx, blocks[0]));
430             return true;
431
432         case opid2('+','P'):
433             out = exprs[0];
434             break;
435         case opid2('-','P'):
436             if ((out = parser->m_fold.op(op, exprs)))
437                 break;
438
439             if (exprs[0]->vtype != TYPE_FLOAT &&
440                 exprs[0]->vtype != TYPE_VECTOR) {
441                     compile_error(ctx, "invalid types used in unary expression: cannot negate type %s",
442                                   type_name[exprs[0]->vtype]);
443                 return false;
444             }
445             if (exprs[0]->vtype == TYPE_FLOAT)
446                 out = (ast_expression*)ast_unary_new(ctx, VINSTR_NEG_F, exprs[0]);
447             else
448                 out = (ast_expression*)ast_unary_new(ctx, VINSTR_NEG_V, exprs[0]);
449             break;
450
451         case opid2('!','P'):
452             if (!(out = parser->m_fold.op(op, exprs))) {
453                 switch (exprs[0]->vtype) {
454                     case TYPE_FLOAT:
455                         out = (ast_expression*)ast_unary_new(ctx, INSTR_NOT_F, exprs[0]);
456                         break;
457                     case TYPE_VECTOR:
458                         out = (ast_expression*)ast_unary_new(ctx, INSTR_NOT_V, exprs[0]);
459                         break;
460                     case TYPE_STRING:
461                         if (OPTS_FLAG(TRUE_EMPTY_STRINGS))
462                             out = (ast_expression*)ast_unary_new(ctx, INSTR_NOT_F, exprs[0]);
463                         else
464                             out = (ast_expression*)ast_unary_new(ctx, INSTR_NOT_S, exprs[0]);
465                         break;
466                     /* we don't constant-fold NOT for these types */
467                     case TYPE_ENTITY:
468                         out = (ast_expression*)ast_unary_new(ctx, INSTR_NOT_ENT, exprs[0]);
469                         break;
470                     case TYPE_FUNCTION:
471                         out = (ast_expression*)ast_unary_new(ctx, INSTR_NOT_FNC, exprs[0]);
472                         break;
473                     default:
474                     compile_error(ctx, "invalid types used in expression: cannot logically negate type %s",
475                                   type_name[exprs[0]->vtype]);
476                     return false;
477                 }
478             }
479             break;
480
481         case opid1('+'):
482             if (exprs[0]->vtype != exprs[1]->vtype ||
483                (exprs[0]->vtype != TYPE_VECTOR && exprs[0]->vtype != TYPE_FLOAT) )
484             {
485                 compile_error(ctx, "invalid types used in expression: cannot add type %s and %s",
486                               type_name[exprs[0]->vtype],
487                               type_name[exprs[1]->vtype]);
488                 return false;
489             }
490             if (!(out = parser->m_fold.op(op, exprs))) {
491                 switch (exprs[0]->vtype) {
492                     case TYPE_FLOAT:
493                         out = fold::binary(ctx, INSTR_ADD_F, exprs[0], exprs[1]);
494                         break;
495                     case TYPE_VECTOR:
496                         out = fold::binary(ctx, INSTR_ADD_V, exprs[0], exprs[1]);
497                         break;
498                     default:
499                         compile_error(ctx, "invalid types used in expression: cannot add type %s and %s",
500                                       type_name[exprs[0]->vtype],
501                                       type_name[exprs[1]->vtype]);
502                         return false;
503                 }
504             }
505             break;
506         case opid1('-'):
507             if  (exprs[0]->vtype != exprs[1]->vtype ||
508                 (exprs[0]->vtype != TYPE_VECTOR && exprs[0]->vtype != TYPE_FLOAT))
509             {
510                 compile_error(ctx, "invalid types used in expression: cannot subtract type %s from %s",
511                               type_name[exprs[1]->vtype],
512                               type_name[exprs[0]->vtype]);
513                 return false;
514             }
515             if (!(out = parser->m_fold.op(op, exprs))) {
516                 switch (exprs[0]->vtype) {
517                     case TYPE_FLOAT:
518                         out = fold::binary(ctx, INSTR_SUB_F, exprs[0], exprs[1]);
519                         break;
520                     case TYPE_VECTOR:
521                         out = fold::binary(ctx, INSTR_SUB_V, exprs[0], exprs[1]);
522                         break;
523                     default:
524                         compile_error(ctx, "invalid types used in expression: cannot subtract type %s from %s",
525                                       type_name[exprs[1]->vtype],
526                                       type_name[exprs[0]->vtype]);
527                         return false;
528                 }
529             }
530             break;
531         case opid1('*'):
532             if (exprs[0]->vtype != exprs[1]->vtype &&
533                 !(exprs[0]->vtype == TYPE_VECTOR &&
534                   exprs[1]->vtype == TYPE_FLOAT) &&
535                 !(exprs[1]->vtype == TYPE_VECTOR &&
536                   exprs[0]->vtype == TYPE_FLOAT)
537                 )
538             {
539                 compile_error(ctx, "invalid types used in expression: cannot multiply types %s and %s",
540                               type_name[exprs[1]->vtype],
541                               type_name[exprs[0]->vtype]);
542                 return false;
543             }
544             if (!(out = parser->m_fold.op(op, exprs))) {
545                 switch (exprs[0]->vtype) {
546                     case TYPE_FLOAT:
547                         if (exprs[1]->vtype == TYPE_VECTOR)
548                             out = fold::binary(ctx, INSTR_MUL_FV, exprs[0], exprs[1]);
549                         else
550                             out = fold::binary(ctx, INSTR_MUL_F, exprs[0], exprs[1]);
551                         break;
552                     case TYPE_VECTOR:
553                         if (exprs[1]->vtype == TYPE_FLOAT)
554                             out = fold::binary(ctx, INSTR_MUL_VF, exprs[0], exprs[1]);
555                         else
556                             out = fold::binary(ctx, INSTR_MUL_V, exprs[0], exprs[1]);
557                         break;
558                     default:
559                         compile_error(ctx, "invalid types used in expression: cannot multiply types %s and %s",
560                                       type_name[exprs[1]->vtype],
561                                       type_name[exprs[0]->vtype]);
562                         return false;
563                 }
564             }
565             break;
566
567         case opid1('/'):
568             if (exprs[1]->vtype != TYPE_FLOAT) {
569                 ast_type_to_string(exprs[0], ty1, sizeof(ty1));
570                 ast_type_to_string(exprs[1], ty2, sizeof(ty2));
571                 compile_error(ctx, "invalid types used in expression: cannot divide types %s and %s", ty1, ty2);
572                 return false;
573             }
574             if (!(out = parser->m_fold.op(op, exprs))) {
575                 if (exprs[0]->vtype == TYPE_FLOAT)
576                     out = fold::binary(ctx, INSTR_DIV_F, exprs[0], exprs[1]);
577                 else {
578                     ast_type_to_string(exprs[0], ty1, sizeof(ty1));
579                     ast_type_to_string(exprs[1], ty2, sizeof(ty2));
580                     compile_error(ctx, "invalid types used in expression: cannot divide types %s and %s", ty1, ty2);
581                     return false;
582                 }
583             }
584             break;
585
586         case opid1('%'):
587             if (NotSameType(TYPE_FLOAT)) {
588                 compile_error(ctx, "invalid types used in expression: cannot perform modulo operation between types %s and %s",
589                     type_name[exprs[0]->vtype],
590                     type_name[exprs[1]->vtype]);
591                 return false;
592             } else if (!(out = parser->m_fold.op(op, exprs))) {
593                 /* generate a call to __builtin_mod */
594                 ast_expression *mod  = parser->m_intrin.func("mod");
595                 ast_call       *call = nullptr;
596                 if (!mod) return false; /* can return null for missing floor */
597
598                 call = ast_call_new(parser_ctx(parser), mod);
599                 call->params.push_back(exprs[0]);
600                 call->params.push_back(exprs[1]);
601
602                 out = (ast_expression*)call;
603             }
604             break;
605
606         case opid2('%','='):
607             compile_error(ctx, "%= is unimplemented");
608             return false;
609
610         case opid1('|'):
611         case opid1('&'):
612         case opid1('^'):
613             if ( !(exprs[0]->vtype == TYPE_FLOAT  && exprs[1]->vtype == TYPE_FLOAT) &&
614                  !(exprs[0]->vtype == TYPE_VECTOR && exprs[1]->vtype == TYPE_FLOAT) &&
615                  !(exprs[0]->vtype == TYPE_VECTOR && exprs[1]->vtype == TYPE_VECTOR))
616             {
617                 compile_error(ctx, "invalid types used in expression: cannot perform bit operations between types %s and %s",
618                               type_name[exprs[0]->vtype],
619                               type_name[exprs[1]->vtype]);
620                 return false;
621             }
622
623             if (!(out = parser->m_fold.op(op, exprs))) {
624                 /*
625                  * IF the first expression is float, the following will be too
626                  * since scalar ^ vector is not allowed.
627                  */
628                 if (exprs[0]->vtype == TYPE_FLOAT) {
629                     out = fold::binary(ctx,
630                         (op->id == opid1('^') ? VINSTR_BITXOR : op->id == opid1('|') ? INSTR_BITOR : INSTR_BITAND),
631                         exprs[0], exprs[1]);
632                 } else {
633                     /*
634                      * The first is a vector: vector is allowed to bitop with vector and
635                      * with scalar, branch here for the second operand.
636                      */
637                     if (exprs[1]->vtype == TYPE_VECTOR) {
638                         /*
639                          * Bitop all the values of the vector components against the
640                          * vectors components in question.
641                          */
642                         out = fold::binary(ctx,
643                             (op->id == opid1('^') ? VINSTR_BITXOR_V : op->id == opid1('|') ? VINSTR_BITOR_V : VINSTR_BITAND_V),
644                             exprs[0], exprs[1]);
645                     } else {
646                         out = fold::binary(ctx,
647                             (op->id == opid1('^') ? VINSTR_BITXOR_VF : op->id == opid1('|') ? VINSTR_BITOR_VF : VINSTR_BITAND_VF),
648                             exprs[0], exprs[1]);
649                     }
650                 }
651             }
652             break;
653
654         case opid2('<','<'):
655         case opid2('>','>'):
656             if (NotSameType(TYPE_FLOAT)) {
657                 compile_error(ctx, "invalid types used in expression: cannot perform shift between types %s and %s",
658                     type_name[exprs[0]->vtype],
659                     type_name[exprs[1]->vtype]);
660                 return false;
661             }
662
663             if (!(out = parser->m_fold.op(op, exprs))) {
664                 ast_expression *shift = parser->m_intrin.func((op->id == opid2('<','<')) ? "__builtin_lshift" : "__builtin_rshift");
665                 ast_call *call  = ast_call_new(parser_ctx(parser), shift);
666                 call->params.push_back(exprs[0]);
667                 call->params.push_back(exprs[1]);
668                 out = (ast_expression*)call;
669             }
670             break;
671
672         case opid3('<','<','='):
673         case opid3('>','>','='):
674             if (NotSameType(TYPE_FLOAT)) {
675                 compile_error(ctx, "invalid types used in expression: cannot perform shift operation between types %s and %s",
676                     type_name[exprs[0]->vtype],
677                     type_name[exprs[1]->vtype]);
678                 return false;
679             }
680
681             if(!(out = parser->m_fold.op(op, exprs))) {
682                 ast_expression *shift = parser->m_intrin.func((op->id == opid3('<','<','=')) ? "__builtin_lshift" : "__builtin_rshift");
683                 ast_call *call  = ast_call_new(parser_ctx(parser), shift);
684                 call->params.push_back(exprs[0]);
685                 call->params.push_back(exprs[1]);
686                 out = (ast_expression*)ast_store_new(
687                     parser_ctx(parser),
688                     INSTR_STORE_F,
689                     exprs[0],
690                     (ast_expression*)call
691                 );
692             }
693
694             break;
695
696         case opid2('|','|'):
697             generated_op += 1; /* INSTR_OR */
698         case opid2('&','&'):
699             generated_op += INSTR_AND;
700             if (!(out = parser->m_fold.op(op, exprs))) {
701                 if (OPTS_FLAG(PERL_LOGIC) && !ast_compare_type(exprs[0], exprs[1])) {
702                     ast_type_to_string(exprs[0], ty1, sizeof(ty1));
703                     ast_type_to_string(exprs[1], ty2, sizeof(ty2));
704                     compile_error(ctx, "invalid types for logical operation with -fperl-logic: %s and %s", ty1, ty2);
705                     return false;
706                 }
707                 for (i = 0; i < 2; ++i) {
708                     if (OPTS_FLAG(CORRECT_LOGIC) && exprs[i]->vtype == TYPE_VECTOR) {
709                         out = (ast_expression*)ast_unary_new(ctx, INSTR_NOT_V, exprs[i]);
710                         if (!out) break;
711                         out = (ast_expression*)ast_unary_new(ctx, INSTR_NOT_F, out);
712                         if (!out) break;
713                         exprs[i] = out; out = nullptr;
714                         if (OPTS_FLAG(PERL_LOGIC)) {
715                             /* here we want to keep the right expressions' type */
716                             break;
717                         }
718                     }
719                     else if (OPTS_FLAG(FALSE_EMPTY_STRINGS) && exprs[i]->vtype == TYPE_STRING) {
720                         out = (ast_expression*)ast_unary_new(ctx, INSTR_NOT_S, exprs[i]);
721                         if (!out) break;
722                         out = (ast_expression*)ast_unary_new(ctx, INSTR_NOT_F, out);
723                         if (!out) break;
724                         exprs[i] = out; out = nullptr;
725                         if (OPTS_FLAG(PERL_LOGIC)) {
726                             /* here we want to keep the right expressions' type */
727                             break;
728                         }
729                     }
730                 }
731                 out = fold::binary(ctx, generated_op, exprs[0], exprs[1]);
732             }
733             break;
734
735         case opid2('?',':'):
736             if (sy->paren.back() != PAREN_TERNARY2) {
737                 compile_error(ctx, "mismatched parenthesis/ternary");
738                 return false;
739             }
740             sy->paren.pop_back();
741             if (!ast_compare_type(exprs[1], exprs[2])) {
742                 ast_type_to_string(exprs[1], ty1, sizeof(ty1));
743                 ast_type_to_string(exprs[2], ty2, sizeof(ty2));
744                 compile_error(ctx, "operands of ternary expression must have the same type, got %s and %s", ty1, ty2);
745                 return false;
746             }
747             if (!(out = parser->m_fold.op(op, exprs)))
748                 out = (ast_expression*)ast_ternary_new(ctx, exprs[0], exprs[1], exprs[2]);
749             break;
750
751         case opid2('*', '*'):
752             if (NotSameType(TYPE_FLOAT)) {
753                 ast_type_to_string(exprs[0], ty1, sizeof(ty1));
754                 ast_type_to_string(exprs[1], ty2, sizeof(ty2));
755                 compile_error(ctx, "invalid types used in exponentiation: %s and %s",
756                     ty1, ty2);
757                 return false;
758             }
759
760             if (!(out = parser->m_fold.op(op, exprs))) {
761                 ast_call *gencall = ast_call_new(parser_ctx(parser), parser->m_intrin.func("pow"));
762                 gencall->params.push_back(exprs[0]);
763                 gencall->params.push_back(exprs[1]);
764                 out = (ast_expression*)gencall;
765             }
766             break;
767
768         case opid2('>', '<'):
769             if (NotSameType(TYPE_VECTOR)) {
770                 ast_type_to_string(exprs[0], ty1, sizeof(ty1));
771                 ast_type_to_string(exprs[1], ty2, sizeof(ty2));
772                 compile_error(ctx, "invalid types used in cross product: %s and %s",
773                     ty1, ty2);
774                 return false;
775             }
776
777             if (!(out = parser->m_fold.op(op, exprs))) {
778                 out = fold::binary(
779                     parser_ctx(parser),
780                     VINSTR_CROSS,
781                     exprs[0],
782                     exprs[1]
783                 );
784             }
785
786             break;
787
788         case opid3('<','=','>'): /* -1, 0, or 1 */
789             if (NotSameType(TYPE_FLOAT)) {
790                 ast_type_to_string(exprs[0], ty1, sizeof(ty1));
791                 ast_type_to_string(exprs[1], ty2, sizeof(ty2));
792                 compile_error(ctx, "invalid types used in comparision: %s and %s",
793                     ty1, ty2);
794
795                 return false;
796             }
797
798             if (!(out = parser->m_fold.op(op, exprs))) {
799                 /* This whole block is NOT fold_binary safe */
800                 ast_binary *eq = ast_binary_new(ctx, INSTR_EQ_F, exprs[0], exprs[1]);
801
802                 eq->refs = AST_REF_NONE;
803
804                     /* if (lt) { */
805                 out = (ast_expression*)ast_ternary_new(ctx,
806                         (ast_expression*)ast_binary_new(ctx, INSTR_LT, exprs[0], exprs[1]),
807                         /* out = -1 */
808                         (ast_expression*)parser->m_fold.imm_float(2),
809                     /* } else { */
810                         /* if (eq) { */
811                         (ast_expression*)ast_ternary_new(ctx, (ast_expression*)eq,
812                             /* out = 0 */
813                             (ast_expression*)parser->m_fold.imm_float(0),
814                         /* } else { */
815                             /* out = 1 */
816                             (ast_expression*)parser->m_fold.imm_float(1)
817                         /* } */
818                         )
819                     /* } */
820                     );
821
822             }
823             break;
824
825         case opid1('>'):
826             generated_op += 1; /* INSTR_GT */
827         case opid1('<'):
828             generated_op += 1; /* INSTR_LT */
829         case opid2('>', '='):
830             generated_op += 1; /* INSTR_GE */
831         case opid2('<', '='):
832             generated_op += INSTR_LE;
833             if (NotSameType(TYPE_FLOAT)) {
834                 compile_error(ctx, "invalid types used in expression: cannot perform comparison between types %s and %s",
835                               type_name[exprs[0]->vtype],
836                               type_name[exprs[1]->vtype]);
837                 return false;
838             }
839             if (!(out = parser->m_fold.op(op, exprs)))
840                 out = fold::binary(ctx, generated_op, exprs[0], exprs[1]);
841             break;
842         case opid2('!', '='):
843             if (exprs[0]->vtype != exprs[1]->vtype) {
844                 compile_error(ctx, "invalid types used in expression: cannot perform comparison between types %s and %s",
845                               type_name[exprs[0]->vtype],
846                               type_name[exprs[1]->vtype]);
847                 return false;
848             }
849             if (!(out = parser->m_fold.op(op, exprs)))
850                 out = fold::binary(ctx, type_ne_instr[exprs[0]->vtype], exprs[0], exprs[1]);
851             break;
852         case opid2('=', '='):
853             if (exprs[0]->vtype != exprs[1]->vtype) {
854                 compile_error(ctx, "invalid types used in expression: cannot perform comparison between types %s and %s",
855                               type_name[exprs[0]->vtype],
856                               type_name[exprs[1]->vtype]);
857                 return false;
858             }
859             if (!(out = parser->m_fold.op(op, exprs)))
860                 out = fold::binary(ctx, type_eq_instr[exprs[0]->vtype], exprs[0], exprs[1]);
861             break;
862
863         case opid1('='):
864             if (ast_istype(exprs[0], ast_entfield)) {
865                 ast_expression *field = ((ast_entfield*)exprs[0])->field;
866                 if (OPTS_FLAG(ADJUST_VECTOR_FIELDS) &&
867                     exprs[0]->vtype == TYPE_FIELD &&
868                     exprs[0]->next->vtype == TYPE_VECTOR)
869                 {
870                     assignop = type_storep_instr[TYPE_VECTOR];
871                 }
872                 else
873                     assignop = type_storep_instr[exprs[0]->vtype];
874                 if (assignop == VINSTR_END || !ast_compare_type(field->next, exprs[1]))
875                 {
876                     ast_type_to_string(field->next, ty1, sizeof(ty1));
877                     ast_type_to_string(exprs[1], ty2, sizeof(ty2));
878                     if (OPTS_FLAG(ASSIGN_FUNCTION_TYPES) &&
879                         field->next->vtype == TYPE_FUNCTION &&
880                         exprs[1]->vtype == TYPE_FUNCTION)
881                     {
882                         (void)!compile_warning(ctx, WARN_ASSIGN_FUNCTION_TYPES,
883                                                "invalid types in assignment: cannot assign %s to %s", ty2, ty1);
884                     }
885                     else
886                         compile_error(ctx, "invalid types in assignment: cannot assign %s to %s", ty2, ty1);
887                 }
888             }
889             else
890             {
891                 if (OPTS_FLAG(ADJUST_VECTOR_FIELDS) &&
892                     exprs[0]->vtype == TYPE_FIELD &&
893                     exprs[0]->next->vtype == TYPE_VECTOR)
894                 {
895                     assignop = type_store_instr[TYPE_VECTOR];
896                 }
897                 else {
898                     assignop = type_store_instr[exprs[0]->vtype];
899                 }
900
901                 if (assignop == VINSTR_END) {
902                     ast_type_to_string(exprs[0], ty1, sizeof(ty1));
903                     ast_type_to_string(exprs[1], ty2, sizeof(ty2));
904                     compile_error(ctx, "invalid types in assignment: cannot assign %s to %s", ty2, ty1);
905                 }
906                 else if (!ast_compare_type(exprs[0], exprs[1]))
907                 {
908                     ast_type_to_string(exprs[0], ty1, sizeof(ty1));
909                     ast_type_to_string(exprs[1], ty2, sizeof(ty2));
910                     if (OPTS_FLAG(ASSIGN_FUNCTION_TYPES) &&
911                         exprs[0]->vtype == TYPE_FUNCTION &&
912                         exprs[1]->vtype == TYPE_FUNCTION)
913                     {
914                         (void)!compile_warning(ctx, WARN_ASSIGN_FUNCTION_TYPES,
915                                                "invalid types in assignment: cannot assign %s to %s", ty2, ty1);
916                     }
917                     else
918                         compile_error(ctx, "invalid types in assignment: cannot assign %s to %s", ty2, ty1);
919                 }
920             }
921             (void)check_write_to(ctx, exprs[0]);
922             /* When we're a vector of part of an entity field we use STOREP */
923             if (ast_istype(exprs[0], ast_member) && ast_istype(((ast_member*)exprs[0])->owner, ast_entfield))
924                 assignop = INSTR_STOREP_F;
925             out = (ast_expression*)ast_store_new(ctx, assignop, exprs[0], exprs[1]);
926             break;
927         case opid3('+','+','P'):
928         case opid3('-','-','P'):
929             /* prefix ++ */
930             if (exprs[0]->vtype != TYPE_FLOAT) {
931                 ast_type_to_string(exprs[0], ty1, sizeof(ty1));
932                 compile_error(ast_ctx(exprs[0]), "invalid type for prefix increment: %s", ty1);
933                 return false;
934             }
935             if (op->id == opid3('+','+','P'))
936                 addop = INSTR_ADD_F;
937             else
938                 addop = INSTR_SUB_F;
939             (void)check_write_to(ast_ctx(exprs[0]), exprs[0]);
940             if (ast_istype(exprs[0], ast_entfield)) {
941                 out = (ast_expression*)ast_binstore_new(ctx, INSTR_STOREP_F, addop,
942                                                         exprs[0],
943                                                         (ast_expression*)parser->m_fold.imm_float(1));
944             } else {
945                 out = (ast_expression*)ast_binstore_new(ctx, INSTR_STORE_F, addop,
946                                                         exprs[0],
947                                                         (ast_expression*)parser->m_fold.imm_float(1));
948             }
949             break;
950         case opid3('S','+','+'):
951         case opid3('S','-','-'):
952             /* prefix ++ */
953             if (exprs[0]->vtype != TYPE_FLOAT) {
954                 ast_type_to_string(exprs[0], ty1, sizeof(ty1));
955                 compile_error(ast_ctx(exprs[0]), "invalid type for suffix increment: %s", ty1);
956                 return false;
957             }
958             if (op->id == opid3('S','+','+')) {
959                 addop = INSTR_ADD_F;
960                 subop = INSTR_SUB_F;
961             } else {
962                 addop = INSTR_SUB_F;
963                 subop = INSTR_ADD_F;
964             }
965             (void)check_write_to(ast_ctx(exprs[0]), exprs[0]);
966             if (ast_istype(exprs[0], ast_entfield)) {
967                 out = (ast_expression*)ast_binstore_new(ctx, INSTR_STOREP_F, addop,
968                                                         exprs[0],
969                                                         (ast_expression*)parser->m_fold.imm_float(1));
970             } else {
971                 out = (ast_expression*)ast_binstore_new(ctx, INSTR_STORE_F, addop,
972                                                         exprs[0],
973                                                         (ast_expression*)parser->m_fold.imm_float(1));
974             }
975             if (!out)
976                 return false;
977             out = fold::binary(ctx, subop,
978                               out,
979                               (ast_expression*)parser->m_fold.imm_float(1));
980
981             break;
982         case opid2('+','='):
983         case opid2('-','='):
984             if (exprs[0]->vtype != exprs[1]->vtype ||
985                 (exprs[0]->vtype != TYPE_VECTOR && exprs[0]->vtype != TYPE_FLOAT) )
986             {
987                 ast_type_to_string(exprs[0], ty1, sizeof(ty1));
988                 ast_type_to_string(exprs[1], ty2, sizeof(ty2));
989                 compile_error(ctx, "invalid types used in expression: cannot add or subtract type %s and %s",
990                               ty1, ty2);
991                 return false;
992             }
993             (void)check_write_to(ctx, exprs[0]);
994             if (ast_istype(exprs[0], ast_entfield))
995                 assignop = type_storep_instr[exprs[0]->vtype];
996             else
997                 assignop = type_store_instr[exprs[0]->vtype];
998             switch (exprs[0]->vtype) {
999                 case TYPE_FLOAT:
1000                     out = (ast_expression*)ast_binstore_new(ctx, assignop,
1001                                                             (op->id == opid2('+','=') ? INSTR_ADD_F : INSTR_SUB_F),
1002                                                             exprs[0], exprs[1]);
1003                     break;
1004                 case TYPE_VECTOR:
1005                     out = (ast_expression*)ast_binstore_new(ctx, assignop,
1006                                                             (op->id == opid2('+','=') ? INSTR_ADD_V : INSTR_SUB_V),
1007                                                             exprs[0], exprs[1]);
1008                     break;
1009                 default:
1010                     compile_error(ctx, "invalid types used in expression: cannot add or subtract type %s and %s",
1011                                   type_name[exprs[0]->vtype],
1012                                   type_name[exprs[1]->vtype]);
1013                     return false;
1014             };
1015             break;
1016         case opid2('*','='):
1017         case opid2('/','='):
1018             if (exprs[1]->vtype != TYPE_FLOAT ||
1019                 !(exprs[0]->vtype == TYPE_FLOAT ||
1020                   exprs[0]->vtype == TYPE_VECTOR))
1021             {
1022                 ast_type_to_string(exprs[0], ty1, sizeof(ty1));
1023                 ast_type_to_string(exprs[1], ty2, sizeof(ty2));
1024                 compile_error(ctx, "invalid types used in expression: %s and %s",
1025                               ty1, ty2);
1026                 return false;
1027             }
1028             (void)check_write_to(ctx, exprs[0]);
1029             if (ast_istype(exprs[0], ast_entfield))
1030                 assignop = type_storep_instr[exprs[0]->vtype];
1031             else
1032                 assignop = type_store_instr[exprs[0]->vtype];
1033             switch (exprs[0]->vtype) {
1034                 case TYPE_FLOAT:
1035                     out = (ast_expression*)ast_binstore_new(ctx, assignop,
1036                                                             (op->id == opid2('*','=') ? INSTR_MUL_F : INSTR_DIV_F),
1037                                                             exprs[0], exprs[1]);
1038                     break;
1039                 case TYPE_VECTOR:
1040                     if (op->id == opid2('*','=')) {
1041                         out = (ast_expression*)ast_binstore_new(ctx, assignop, INSTR_MUL_VF,
1042                                                                 exprs[0], exprs[1]);
1043                     } else {
1044                         out = fold::binary(ctx, INSTR_DIV_F,
1045                                          (ast_expression*)parser->m_fold.imm_float(1),
1046                                          exprs[1]);
1047                         if (!out) {
1048                             compile_error(ctx, "internal error: failed to generate division");
1049                             return false;
1050                         }
1051                         out = (ast_expression*)ast_binstore_new(ctx, assignop, INSTR_MUL_VF,
1052                                                                 exprs[0], out);
1053                     }
1054                     break;
1055                 default:
1056                     compile_error(ctx, "invalid types used in expression: cannot add or subtract type %s and %s",
1057                                   type_name[exprs[0]->vtype],
1058                                   type_name[exprs[1]->vtype]);
1059                     return false;
1060             };
1061             break;
1062         case opid2('&','='):
1063         case opid2('|','='):
1064         case opid2('^','='):
1065             if (NotSameType(TYPE_FLOAT) && NotSameType(TYPE_VECTOR)) {
1066                 ast_type_to_string(exprs[0], ty1, sizeof(ty1));
1067                 ast_type_to_string(exprs[1], ty2, sizeof(ty2));
1068                 compile_error(ctx, "invalid types used in expression: %s and %s",
1069                               ty1, ty2);
1070                 return false;
1071             }
1072             (void)check_write_to(ctx, exprs[0]);
1073             if (ast_istype(exprs[0], ast_entfield))
1074                 assignop = type_storep_instr[exprs[0]->vtype];
1075             else
1076                 assignop = type_store_instr[exprs[0]->vtype];
1077             if (exprs[0]->vtype == TYPE_FLOAT)
1078                 out = (ast_expression*)ast_binstore_new(ctx, assignop,
1079                                                         (op->id == opid2('^','=') ? VINSTR_BITXOR : op->id == opid2('&','=') ? INSTR_BITAND : INSTR_BITOR),
1080                                                         exprs[0], exprs[1]);
1081             else
1082                 out = (ast_expression*)ast_binstore_new(ctx, assignop,
1083                                                         (op->id == opid2('^','=') ? VINSTR_BITXOR_V : op->id == opid2('&','=') ? VINSTR_BITAND_V : VINSTR_BITOR_V),
1084                                                         exprs[0], exprs[1]);
1085             break;
1086         case opid3('&','~','='):
1087             /* This is like: a &= ~(b);
1088              * But QC has no bitwise-not, so we implement it as
1089              * a -= a & (b);
1090              */
1091             if (NotSameType(TYPE_FLOAT) && NotSameType(TYPE_VECTOR)) {
1092                 ast_type_to_string(exprs[0], ty1, sizeof(ty1));
1093                 ast_type_to_string(exprs[1], ty2, sizeof(ty2));
1094                 compile_error(ctx, "invalid types used in expression: %s and %s",
1095                               ty1, ty2);
1096                 return false;
1097             }
1098             if (ast_istype(exprs[0], ast_entfield))
1099                 assignop = type_storep_instr[exprs[0]->vtype];
1100             else
1101                 assignop = type_store_instr[exprs[0]->vtype];
1102             if (exprs[0]->vtype == TYPE_FLOAT)
1103                 out = fold::binary(ctx, INSTR_BITAND, exprs[0], exprs[1]);
1104             else
1105                 out = fold::binary(ctx, VINSTR_BITAND_V, exprs[0], exprs[1]);
1106             if (!out)
1107                 return false;
1108             (void)check_write_to(ctx, exprs[0]);
1109             if (exprs[0]->vtype == TYPE_FLOAT)
1110                 asbinstore = ast_binstore_new(ctx, assignop, INSTR_SUB_F, exprs[0], out);
1111             else
1112                 asbinstore = ast_binstore_new(ctx, assignop, INSTR_SUB_V, exprs[0], out);
1113             asbinstore->keep_dest = true;
1114             out = (ast_expression*)asbinstore;
1115             break;
1116
1117         case opid3('l', 'e', 'n'):
1118             if (exprs[0]->vtype != TYPE_STRING && exprs[0]->vtype != TYPE_ARRAY) {
1119                 ast_type_to_string(exprs[0], ty1, sizeof(ty1));
1120                 compile_error(ast_ctx(exprs[0]), "invalid type for length operator: %s", ty1);
1121                 return false;
1122             }
1123             /* strings must be const, arrays are statically sized */
1124             if (exprs[0]->vtype == TYPE_STRING &&
1125                 !(((ast_value*)exprs[0])->hasvalue && ((ast_value*)exprs[0])->cvq == CV_CONST))
1126             {
1127                 compile_error(ast_ctx(exprs[0]), "operand of length operator not a valid constant expression");
1128                 return false;
1129             }
1130             out = parser->m_fold.op(op, exprs);
1131             break;
1132
1133         case opid2('~', 'P'):
1134             if (exprs[0]->vtype != TYPE_FLOAT && exprs[0]->vtype != TYPE_VECTOR) {
1135                 ast_type_to_string(exprs[0], ty1, sizeof(ty1));
1136                 compile_error(ast_ctx(exprs[0]), "invalid type for bit not: %s", ty1);
1137                 return false;
1138             }
1139             if (!(out = parser->m_fold.op(op, exprs))) {
1140                 if (exprs[0]->vtype == TYPE_FLOAT) {
1141                     out = fold::binary(ctx, INSTR_SUB_F, (ast_expression*)parser->m_fold.imm_float(2), exprs[0]);
1142                 } else {
1143                     out = fold::binary(ctx, INSTR_SUB_V, (ast_expression*)parser->m_fold.imm_vector(1), exprs[0]);
1144                 }
1145             }
1146             break;
1147     }
1148 #undef NotSameType
1149     if (!out) {
1150         compile_error(ctx, "failed to apply operator %s", op->op);
1151         return false;
1152     }
1153
1154     sy->out.push_back(syexp(ctx, out));
1155     return true;
1156 }
1157
1158 static bool parser_close_call(parser_t *parser, shunt *sy)
1159 {
1160     /* was a function call */
1161     ast_expression *fun;
1162     ast_value      *funval = nullptr;
1163     ast_call       *call;
1164
1165     size_t          fid;
1166     size_t          paramcount, i;
1167     bool            fold = true;
1168
1169     fid = sy->ops.back().off;
1170     sy->ops.pop_back();
1171
1172     /* out[fid] is the function
1173      * everything above is parameters...
1174      */
1175     if (sy->argc.empty()) {
1176         parseerror(parser, "internal error: no argument counter available");
1177         return false;
1178     }
1179
1180     paramcount = sy->argc.back();
1181     sy->argc.pop_back();
1182
1183     if (sy->out.size() < fid) {
1184         parseerror(parser, "internal error: broken function call %zu < %zu+%zu\n",
1185                    sy->out.size(),
1186                    fid,
1187                    paramcount);
1188         return false;
1189     }
1190
1191     /*
1192      * TODO handle this at the intrinsic level with an ast_intrinsic
1193      * node and codegen.
1194      */
1195     if ((fun = sy->out[fid].out) == parser->m_intrin.debug_typestring()) {
1196         char ty[1024];
1197         if (fid+2 != sy->out.size() || sy->out.back().block) {
1198             parseerror(parser, "intrinsic __builtin_debug_typestring requires exactly 1 parameter");
1199             return false;
1200         }
1201         ast_type_to_string(sy->out.back().out, ty, sizeof(ty));
1202         ast_unref(sy->out.back().out);
1203         sy->out[fid] = syexp(ast_ctx(sy->out.back().out),
1204                              (ast_expression*)parser->m_fold.constgen_string(ty, false));
1205         sy->out.pop_back();
1206         return true;
1207     }
1208
1209     /*
1210      * Now we need to determine if the function that is being called is
1211      * an intrinsic so we can evaluate if the arguments to it are constant
1212      * and than fruitfully fold them.
1213      */
1214 #define fold_can_1(X)  \
1215     (ast_istype(((ast_expression*)(X)), ast_value) && (X)->hasvalue && ((X)->cvq == CV_CONST) && \
1216                 ((ast_expression*)(X))->vtype != TYPE_FUNCTION)
1217
1218     if (fid + 1 < sy->out.size())
1219         ++paramcount;
1220
1221     for (i = 0; i < paramcount; ++i) {
1222         if (!fold_can_1((ast_value*)sy->out[fid + 1 + i].out)) {
1223             fold = false;
1224             break;
1225         }
1226     }
1227
1228     /*
1229      * All is well which ends well, if we make it into here we can ignore the
1230      * intrinsic call and just evaluate it i.e constant fold it.
1231      */
1232     if (fold && ast_istype(fun, ast_value) && ((ast_value*)fun)->intrinsic) {
1233         ast_expression **exprs  = nullptr;
1234         ast_expression *foldval = nullptr;
1235
1236         for (i = 0; i < paramcount; i++)
1237             vec_push(exprs, sy->out[fid+1 + i].out);
1238
1239         if (!(foldval = parser->m_intrin.do_fold((ast_value*)fun, exprs))) {
1240             vec_free(exprs);
1241             goto fold_leave;
1242         }
1243
1244         /*
1245          * Blub: what sorts of unreffing and resizing of
1246          * sy->out should I be doing here?
1247          */
1248         sy->out[fid] = syexp(foldval->node.context, foldval);
1249         sy->out.erase(sy->out.end() - paramcount, sy->out.end());
1250         vec_free(exprs);
1251
1252         return true;
1253     }
1254
1255     fold_leave:
1256     call = ast_call_new(sy->ops[sy->ops.size()].ctx, fun);
1257
1258     if (!call)
1259         return false;
1260
1261     if (fid+1 + paramcount != sy->out.size()) {
1262         parseerror(parser, "internal error: parameter count mismatch: (%zu+1+%zu), %zu",
1263                    fid,
1264                    paramcount,
1265                    sy->out.size());
1266         return false;
1267     }
1268
1269     for (i = 0; i < paramcount; ++i)
1270         call->params.push_back(sy->out[fid+1 + i].out);
1271     sy->out.erase(sy->out.end() - paramcount, sy->out.end());
1272     (void)!ast_call_check_types(call, parser->function->vtype->expression.varparam);
1273     if (parser->max_param_count < paramcount)
1274         parser->max_param_count = paramcount;
1275
1276     if (ast_istype(fun, ast_value)) {
1277         funval = (ast_value*)fun;
1278         if ((fun->flags & AST_FLAG_VARIADIC) &&
1279             !(/*funval->cvq == CV_CONST && */ funval->hasvalue && funval->constval.vfunc->builtin))
1280         {
1281             call->va_count = (ast_expression*)parser->m_fold.constgen_float((qcfloat_t)paramcount, false);
1282         }
1283     }
1284
1285     /* overwrite fid, the function, with a call */
1286     sy->out[fid] = syexp(call->expression.node.context, (ast_expression*)call);