2 * Copyright (C) 2012, 2013
6 * Permission is hereby granted, free of charge, to any person obtaining a copy of
7 * this software and associated documentation files (the "Software"), to deal in
8 * the Software without restriction, including without limitation the rights to
9 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
10 * of the Software, and to permit persons to whom the Software is furnished to do
11 * so, subject to the following conditions:
13 * The above copyright notice and this permission notice shall be included in all
14 * copies or substantial portions of the Software.
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
31 /* beginning of locals */
32 #define PARSER_HT_LOCALS 2
33 #define PARSER_HT_SIZE 128
34 #define TYPEDEF_HT_SIZE 16
36 typedef struct parser_s {
42 ast_expression **globals;
43 ast_expression **fields;
44 ast_function **functions;
45 ast_value **imm_float;
46 ast_value **imm_string;
47 ast_value **imm_vector;
52 /* must be deleted first, they reference immediates and values */
53 ast_value **accessors;
55 ast_value *imm_float_zero;
56 ast_value *imm_float_one;
57 ast_value *imm_float_neg_one;
59 ast_value *imm_vector_zero;
62 ast_value *reserved_version;
67 ast_function *function;
70 /* All the labels the function defined...
71 * Should they be in ast_function instead?
76 const char **continues;
78 /* A list of hashtables for each scope */
84 /* same as above but for the spelling corrector */
85 correct_trie_t **correct_variables;
86 size_t ***correct_variables_score; /* vector of vector of size_t* */
88 /* not to be used directly, we use the hash table */
89 ast_expression **_locals;
91 ast_value **_typedefs;
92 size_t *_blocktypedefs;
95 /* we store the '=' operator info */
96 const oper_info *assign_op;
99 ast_value *const_vec[3];
104 /* collected information */
105 size_t max_param_count;
114 static ast_expression * const intrinsic_debug_typestring = (ast_expression*)0x1;
116 static void parser_enterblock(parser_t *parser);
117 static bool parser_leaveblock(parser_t *parser);
118 static void parser_addlocal(parser_t *parser, const char *name, ast_expression *e);
119 static void parser_addglobal(parser_t *parser, const char *name, ast_expression *e);
120 static bool parse_typedef(parser_t *parser);
121 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);
122 static ast_block* parse_block(parser_t *parser);
123 static bool parse_block_into(parser_t *parser, ast_block *block);
124 static bool parse_statement_or_block(parser_t *parser, ast_expression **out);
125 static bool parse_statement(parser_t *parser, ast_block *block, ast_expression **out, bool allow_cases);
126 static ast_expression* parse_expression_leave(parser_t *parser, bool stopatcomma, bool truthvalue, bool with_labels);
127 static ast_expression* parse_expression(parser_t *parser, bool stopatcomma, bool with_labels);
128 static ast_value* parser_create_array_setter_proto(parser_t *parser, ast_value *array, const char *funcname);
129 static ast_value* parser_create_array_getter_proto(parser_t *parser, ast_value *array, const ast_expression *elemtype, const char *funcname);
130 static ast_value *parse_typename(parser_t *parser, ast_value **storebase, ast_value *cached_typedef);
133 static void parseerror(parser_t *parser, const char *fmt, ...)
139 /*vcompile_error(parser->lex->tok.ctx, data);*/
140 vcompile_error(parser->lex->tok.ctx, fmt, ap);
143 if (OPTS_OPTION_BOOL(OPTION_DIAGNOSTICS))
144 diagnostic_calculate(parser->lex->name, parser->lex->line, parser->lex->column, parser->diagnostic);
147 /* returns true if it counts as an error */
148 static bool GMQCC_WARN parsewarning(parser_t *parser, int warntype, const char *fmt, ...)
153 r = vcompile_warning(parser->lex->tok.ctx, warntype, fmt, ap);
156 if (OPTS_OPTION_BOOL(OPTION_DIAGNOSTICS))
157 diagnostic_calculate(parser->lex->name, parser->lex->line, parser->lex->column, parser->diagnostic);
161 /**********************************************************************
162 * some maths used for constant folding
165 vector vec3_add(vector a, vector b)
174 vector vec3_sub(vector a, vector b)
183 qcfloat vec3_mulvv(vector a, vector b)
185 return (a.x * b.x + a.y * b.y + a.z * b.z);
188 vector vec3_mulvf(vector a, float b)
197 /**********************************************************************
201 static bool parser_next(parser_t *parser)
203 /* lex_do kills the previous token */
204 parser->tok = lex_do(parser->lex);
205 if (parser->tok == TOKEN_EOF)
207 if (parser->tok >= TOKEN_ERROR) {
208 parseerror(parser, "lex error");
214 #define parser_tokval(p) ((p)->lex->tok.value)
215 #define parser_token(p) (&((p)->lex->tok))
216 #define parser_ctx(p) ((p)->lex->tok.ctx)
218 static ast_value* parser_const_float(parser_t *parser, double d)
223 for (i = 0; i < vec_size(parser->imm_float); ++i) {
224 const double compare = parser->imm_float[i]->constval.vfloat;
225 if (memcmp((const void*)&compare, (const void *)&d, sizeof(double)) == 0)
226 return parser->imm_float[i];
229 ctx = parser_ctx(parser);
231 memset(&ctx, 0, sizeof(ctx));
233 out = ast_value_new(ctx, "#IMMEDIATE", TYPE_FLOAT);
235 out->hasvalue = true;
237 out->constval.vfloat = d;
238 vec_push(parser->imm_float, out);
242 static ast_value* parser_const_float_0(parser_t *parser)
244 if (!parser->imm_float_zero)
245 parser->imm_float_zero = parser_const_float(parser, 0);
246 return parser->imm_float_zero;
249 static ast_value* parser_const_float_neg1(parser_t *parser) {
250 if (!parser->imm_float_neg_one)
251 parser->imm_float_neg_one = parser_const_float(parser, -1);
252 return parser->imm_float_neg_one;
255 static ast_value* parser_const_float_1(parser_t *parser)
257 if (!parser->imm_float_one)
258 parser->imm_float_one = parser_const_float(parser, 1);
259 return parser->imm_float_one;
262 static char *parser_strdup(const char *str)
265 /* actually dup empty strings */
266 char *out = (char*)mem_a(1);
270 return util_strdup(str);
273 static ast_value* parser_const_string(parser_t *parser, const char *str, bool dotranslate)
275 size_t hash = util_hthash(parser->ht_imm_string, str);
277 if ( (out = (ast_value*)util_htgeth(parser->ht_imm_string, str, hash)) ) {
278 if (dotranslate && out->name[0] == '#') {
280 util_snprintf(name, sizeof(name), "dotranslate_%lu", (unsigned long)(parser->translated++));
281 ast_value_set_name(out, name);
282 out->expression.flags |= AST_FLAG_INCLUDE_DEF;
287 for (i = 0; i < vec_size(parser->imm_string); ++i) {
288 if (!strcmp(parser->imm_string[i]->constval.vstring, str))
289 return parser->imm_string[i];
294 util_snprintf(name, sizeof(name), "dotranslate_%lu", (unsigned long)(parser->translated++));
295 out = ast_value_new(parser_ctx(parser), name, TYPE_STRING);
296 out->expression.flags |= AST_FLAG_INCLUDE_DEF;
298 out = ast_value_new(parser_ctx(parser), "#IMMEDIATE", TYPE_STRING);
300 out->hasvalue = true;
302 out->constval.vstring = parser_strdup(str);
303 vec_push(parser->imm_string, out);
304 util_htseth(parser->ht_imm_string, str, hash, out);
308 static ast_value* parser_const_vector(parser_t *parser, vector v)
312 for (i = 0; i < vec_size(parser->imm_vector); ++i) {
313 if (!memcmp(&parser->imm_vector[i]->constval.vvec, &v, sizeof(v)))
314 return parser->imm_vector[i];
316 out = ast_value_new(parser_ctx(parser), "#IMMEDIATE", TYPE_VECTOR);
318 out->hasvalue = true;
320 out->constval.vvec = v;
321 vec_push(parser->imm_vector, out);
325 static ast_value* parser_const_vector_f(parser_t *parser, float x, float y, float z)
331 return parser_const_vector(parser, v);
334 static ast_value* parser_const_vector_0(parser_t *parser)
336 if (!parser->imm_vector_zero)
337 parser->imm_vector_zero = parser_const_vector_f(parser, 0, 0, 0);
338 return parser->imm_vector_zero;
341 static ast_expression* parser_find_field(parser_t *parser, const char *name)
343 return ( ast_expression*)util_htget(parser->htfields, name);
346 static ast_expression* parser_find_label(parser_t *parser, const char *name)
349 for(i = 0; i < vec_size(parser->labels); i++)
350 if (!strcmp(parser->labels[i]->name, name))
351 return (ast_expression*)parser->labels[i];
355 static ast_expression* parser_find_global(parser_t *parser, const char *name)
357 ast_expression *var = (ast_expression*)util_htget(parser->aliases, parser_tokval(parser));
360 return (ast_expression*)util_htget(parser->htglobals, name);
363 static ast_expression* parser_find_param(parser_t *parser, const char *name)
367 if (!parser->function)
369 fun = parser->function->vtype;
370 for (i = 0; i < vec_size(fun->expression.params); ++i) {
371 if (!strcmp(fun->expression.params[i]->name, name))
372 return (ast_expression*)(fun->expression.params[i]);
377 static ast_expression* parser_find_local(parser_t *parser, const char *name, size_t upto, bool *isparam)
382 hash = util_hthash(parser->htglobals, name);
385 for (i = vec_size(parser->variables); i > upto;) {
387 if ( (e = (ast_expression*)util_htgeth(parser->variables[i], name, hash)) )
391 return parser_find_param(parser, name);
394 static ast_expression* parser_find_var(parser_t *parser, const char *name)
398 v = parser_find_local(parser, name, 0, &dummy);
399 if (!v) v = parser_find_global(parser, name);
403 static ast_value* parser_find_typedef(parser_t *parser, const char *name, size_t upto)
407 hash = util_hthash(parser->typedefs[0], name);
409 for (i = vec_size(parser->typedefs); i > upto;) {
411 if ( (e = (ast_value*)util_htgeth(parser->typedefs[i], name, hash)) )
417 /* include intrinsics */
422 size_t etype; /* 0 = expression, others are operators */
426 ast_block *block; /* for commas and function calls */
445 static sy_elem syexp(lex_ctx ctx, ast_expression *v) {
456 static sy_elem syblock(lex_ctx ctx, ast_block *v) {
460 e.out = (ast_expression*)v;
467 static sy_elem syop(lex_ctx ctx, const oper_info *op) {
469 e.etype = 1 + (op - operators);
478 static sy_elem syparen(lex_ctx ctx, size_t off) {
489 /* With regular precedence rules, ent.foo[n] is the same as (ent.foo)[n],
490 * so we need to rotate it to become ent.(foo[n]).
492 static bool rotate_entfield_array_index_nodes(ast_expression **out)
494 ast_array_index *index, *oldindex;
495 ast_entfield *entfield;
499 ast_expression *entity;
501 lex_ctx ctx = ast_ctx(*out);
503 if (!ast_istype(*out, ast_array_index))
505 index = (ast_array_index*)*out;
507 if (!ast_istype(index->array, ast_entfield))
509 entfield = (ast_entfield*)index->array;
511 if (!ast_istype(entfield->field, ast_value))
513 field = (ast_value*)entfield->field;
516 entity = entfield->entity;
520 index = ast_array_index_new(ctx, (ast_expression*)field, sub);
521 entfield = ast_entfield_new(ctx, entity, (ast_expression*)index);
522 *out = (ast_expression*)entfield;
524 oldindex->array = NULL;
525 oldindex->index = NULL;
526 ast_delete(oldindex);
531 static bool immediate_is_true(lex_ctx ctx, ast_value *v)
533 switch (v->expression.vtype) {
535 return !!v->constval.vfloat;
537 return !!v->constval.vint;
539 if (OPTS_FLAG(CORRECT_LOGIC))
540 return v->constval.vvec.x &&
541 v->constval.vvec.y &&
544 return !!(v->constval.vvec.x);
546 if (!v->constval.vstring)
548 if (v->constval.vstring && OPTS_FLAG(TRUE_EMPTY_STRINGS))
550 return !!v->constval.vstring[0];
552 compile_error(ctx, "internal error: immediate_is_true on invalid type");
553 return !!v->constval.vfunc;
557 static bool parser_sy_apply_operator(parser_t *parser, shunt *sy)
561 ast_expression *out = NULL;
562 ast_expression *exprs[3];
563 ast_block *blocks[3];
564 ast_value *asvalue[3];
565 ast_binstore *asbinstore;
566 size_t i, assignop, addop, subop;
567 qcint generated_op = 0;
572 if (!vec_size(sy->ops)) {
573 parseerror(parser, "internal error: missing operator");
577 if (vec_last(sy->ops).isparen) {
578 parseerror(parser, "unmatched parenthesis");
582 op = &operators[vec_last(sy->ops).etype - 1];
583 ctx = vec_last(sy->ops).ctx;
585 if (vec_size(sy->out) < op->operands) {
586 compile_error(ctx, "internal error: not enough operands: %i (operator %s (%i))", vec_size(sy->out),
587 op->op, (int)op->id);
591 vec_shrinkby(sy->ops, 1);
593 /* op(:?) has no input and no output */
597 vec_shrinkby(sy->out, op->operands);
598 for (i = 0; i < op->operands; ++i) {
599 exprs[i] = sy->out[vec_size(sy->out)+i].out;
600 blocks[i] = sy->out[vec_size(sy->out)+i].block;
601 asvalue[i] = (ast_value*)exprs[i];
603 if (exprs[i]->vtype == TYPE_NOEXPR &&
604 !(i != 0 && op->id == opid2('?',':')) &&
605 !(i == 1 && op->id == opid1('.')))
607 if (ast_istype(exprs[i], ast_label))
608 compile_error(ast_ctx(exprs[i]), "expected expression, got an unknown identifier");
610 compile_error(ast_ctx(exprs[i]), "not an expression");
611 (void)!compile_warning(ast_ctx(exprs[i]), WARN_DEBUG, "expression %u\n", (unsigned int)i);
615 if (blocks[0] && !vec_size(blocks[0]->exprs) && op->id != opid1(',')) {
616 compile_error(ctx, "internal error: operator cannot be applied on empty blocks");
620 #define NotSameType(T) \
621 (exprs[0]->vtype != exprs[1]->vtype || \
622 exprs[0]->vtype != T)
623 #define CanConstFold1(A) \
624 (ast_istype((A), ast_value) && ((ast_value*)(A))->hasvalue && (((ast_value*)(A))->cvq == CV_CONST) &&\
625 (A)->vtype != TYPE_FUNCTION)
626 #define CanConstFold(A, B) \
627 (CanConstFold1(A) && CanConstFold1(B))
628 #define ConstV(i) (asvalue[(i)]->constval.vvec)
629 #define ConstF(i) (asvalue[(i)]->constval.vfloat)
630 #define ConstS(i) (asvalue[(i)]->constval.vstring)
634 compile_error(ctx, "internal error: unhandled operator: %s (%i)", op->op, (int)op->id);
638 if (exprs[0]->vtype == TYPE_VECTOR &&
639 exprs[1]->vtype == TYPE_NOEXPR)
641 if (exprs[1] == (ast_expression*)parser->const_vec[0])
642 out = (ast_expression*)ast_member_new(ctx, exprs[0], 0, NULL);
643 else if (exprs[1] == (ast_expression*)parser->const_vec[1])
644 out = (ast_expression*)ast_member_new(ctx, exprs[0], 1, NULL);
645 else if (exprs[1] == (ast_expression*)parser->const_vec[2])
646 out = (ast_expression*)ast_member_new(ctx, exprs[0], 2, NULL);
648 compile_error(ctx, "access to invalid vector component");
652 else if (exprs[0]->vtype == TYPE_ENTITY) {
653 if (exprs[1]->vtype != TYPE_FIELD) {
654 compile_error(ast_ctx(exprs[1]), "type error: right hand of member-operand should be an entity-field");
657 out = (ast_expression*)ast_entfield_new(ctx, exprs[0], exprs[1]);
659 else if (exprs[0]->vtype == TYPE_VECTOR) {
660 compile_error(ast_ctx(exprs[1]), "vectors cannot be accessed this way");
664 compile_error(ast_ctx(exprs[1]), "type error: member-of operator on something that is not an entity or vector");
670 if (exprs[0]->vtype != TYPE_ARRAY &&
671 !(exprs[0]->vtype == TYPE_FIELD &&
672 exprs[0]->next->vtype == TYPE_ARRAY))
674 ast_type_to_string(exprs[0], ty1, sizeof(ty1));
675 compile_error(ast_ctx(exprs[0]), "cannot index value of type %s", ty1);
678 if (exprs[1]->vtype != TYPE_FLOAT) {
679 ast_type_to_string(exprs[0], ty1, sizeof(ty1));
680 compile_error(ast_ctx(exprs[1]), "index must be of type float, not %s", ty1);
683 out = (ast_expression*)ast_array_index_new(ctx, exprs[0], exprs[1]);
684 if (rotate_entfield_array_index_nodes(&out))
687 /* This is not broken in fteqcc anymore */
688 if (OPTS_OPTION_U32(OPTION_STANDARD) != COMPILER_GMQCC) {
689 /* this error doesn't need to make us bail out */
690 (void)!parsewarning(parser, WARN_EXTENSIONS,
691 "accessing array-field members of an entity without parenthesis\n"
692 " -> this is an extension from -std=gmqcc");
699 if (vec_size(sy->paren) && vec_last(sy->paren) == PAREN_FUNC) {
700 vec_push(sy->out, syexp(ctx, exprs[0]));
701 vec_push(sy->out, syexp(ctx, exprs[1]));
702 vec_last(sy->argc)++;
706 if (!ast_block_add_expr(blocks[0], exprs[1]))
709 blocks[0] = ast_block_new(ctx);
710 if (!ast_block_add_expr(blocks[0], exprs[0]) ||
711 !ast_block_add_expr(blocks[0], exprs[1]))
716 ast_block_set_type(blocks[0], exprs[1]);
718 vec_push(sy->out, syblock(ctx, blocks[0]));
725 switch (exprs[0]->vtype) {
727 if (CanConstFold1(exprs[0]))
728 out = (ast_expression*)parser_const_float(parser, -ConstF(0));
730 out = (ast_expression*)ast_binary_new(ctx, INSTR_SUB_F,
731 (ast_expression*)parser_const_float_0(parser),
735 if (CanConstFold1(exprs[0]))
736 out = (ast_expression*)parser_const_vector_f(parser,
737 -ConstV(0).x, -ConstV(0).y, -ConstV(0).z);
739 out = (ast_expression*)ast_binary_new(ctx, INSTR_SUB_V,
740 (ast_expression*)parser_const_vector_0(parser),
744 compile_error(ctx, "invalid types used in expression: cannot negate type %s",
745 type_name[exprs[0]->vtype]);
751 switch (exprs[0]->vtype) {
753 if (CanConstFold1(exprs[0]))
754 out = (ast_expression*)parser_const_float(parser, !ConstF(0));
756 out = (ast_expression*)ast_unary_new(ctx, INSTR_NOT_F, exprs[0]);
759 if (CanConstFold1(exprs[0]))
760 out = (ast_expression*)parser_const_float(parser,
761 (!ConstV(0).x && !ConstV(0).y && !ConstV(0).z));
763 out = (ast_expression*)ast_unary_new(ctx, INSTR_NOT_V, exprs[0]);
766 if (CanConstFold1(exprs[0])) {
767 if (OPTS_FLAG(TRUE_EMPTY_STRINGS))
768 out = (ast_expression*)parser_const_float(parser, !ConstS(0));
770 out = (ast_expression*)parser_const_float(parser, !ConstS(0) || !*ConstS(0));
772 if (OPTS_FLAG(TRUE_EMPTY_STRINGS))
773 out = (ast_expression*)ast_unary_new(ctx, INSTR_NOT_F, exprs[0]);
775 out = (ast_expression*)ast_unary_new(ctx, INSTR_NOT_S, exprs[0]);
778 /* we don't constant-fold NOT for these types */
780 out = (ast_expression*)ast_unary_new(ctx, INSTR_NOT_ENT, exprs[0]);
783 out = (ast_expression*)ast_unary_new(ctx, INSTR_NOT_FNC, exprs[0]);
786 compile_error(ctx, "invalid types used in expression: cannot logically negate type %s",
787 type_name[exprs[0]->vtype]);
793 if (exprs[0]->vtype != exprs[1]->vtype ||
794 (exprs[0]->vtype != TYPE_VECTOR && exprs[0]->vtype != TYPE_FLOAT) )
796 compile_error(ctx, "invalid types used in expression: cannot add type %s and %s",
797 type_name[exprs[0]->vtype],
798 type_name[exprs[1]->vtype]);
801 switch (exprs[0]->vtype) {
803 if (CanConstFold(exprs[0], exprs[1]))
805 out = (ast_expression*)parser_const_float(parser, ConstF(0) + ConstF(1));
808 out = (ast_expression*)ast_binary_new(ctx, INSTR_ADD_F, exprs[0], exprs[1]);
811 if (CanConstFold(exprs[0], exprs[1]))
812 out = (ast_expression*)parser_const_vector(parser, vec3_add(ConstV(0), ConstV(1)));
814 out = (ast_expression*)ast_binary_new(ctx, INSTR_ADD_V, exprs[0], exprs[1]);
817 compile_error(ctx, "invalid types used in expression: cannot add type %s and %s",
818 type_name[exprs[0]->vtype],
819 type_name[exprs[1]->vtype]);
824 if (exprs[0]->vtype != exprs[1]->vtype ||
825 (exprs[0]->vtype != TYPE_VECTOR && exprs[0]->vtype != TYPE_FLOAT) )
827 compile_error(ctx, "invalid types used in expression: cannot subtract type %s from %s",
828 type_name[exprs[1]->vtype],
829 type_name[exprs[0]->vtype]);
832 switch (exprs[0]->vtype) {
834 if (CanConstFold(exprs[0], exprs[1]))
835 out = (ast_expression*)parser_const_float(parser, ConstF(0) - ConstF(1));
837 out = (ast_expression*)ast_binary_new(ctx, INSTR_SUB_F, exprs[0], exprs[1]);
840 if (CanConstFold(exprs[0], exprs[1]))
841 out = (ast_expression*)parser_const_vector(parser, vec3_sub(ConstV(0), ConstV(1)));
843 out = (ast_expression*)ast_binary_new(ctx, INSTR_SUB_V, exprs[0], exprs[1]);
846 compile_error(ctx, "invalid types used in expression: cannot subtract type %s from %s",
847 type_name[exprs[1]->vtype],
848 type_name[exprs[0]->vtype]);
853 if (exprs[0]->vtype != exprs[1]->vtype &&
854 !(exprs[0]->vtype == TYPE_VECTOR &&
855 exprs[1]->vtype == TYPE_FLOAT) &&
856 !(exprs[1]->vtype == TYPE_VECTOR &&
857 exprs[0]->vtype == TYPE_FLOAT)
860 compile_error(ctx, "invalid types used in expression: cannot multiply types %s and %s",
861 type_name[exprs[1]->vtype],
862 type_name[exprs[0]->vtype]);
865 switch (exprs[0]->vtype) {
867 if (exprs[1]->vtype == TYPE_VECTOR)
869 if (CanConstFold(exprs[0], exprs[1]))
870 out = (ast_expression*)parser_const_vector(parser, vec3_mulvf(ConstV(1), ConstF(0)));
872 out = (ast_expression*)ast_binary_new(ctx, INSTR_MUL_FV, exprs[0], exprs[1]);
876 if (CanConstFold(exprs[0], exprs[1]))
877 out = (ast_expression*)parser_const_float(parser, ConstF(0) * ConstF(1));
879 out = (ast_expression*)ast_binary_new(ctx, INSTR_MUL_F, exprs[0], exprs[1]);
883 if (exprs[1]->vtype == TYPE_FLOAT)
885 if (CanConstFold(exprs[0], exprs[1]))
886 out = (ast_expression*)parser_const_vector(parser, vec3_mulvf(ConstV(0), ConstF(1)));
888 out = (ast_expression*)ast_binary_new(ctx, INSTR_MUL_VF, exprs[0], exprs[1]);
892 if (CanConstFold(exprs[0], exprs[1]))
893 out = (ast_expression*)parser_const_float(parser, vec3_mulvv(ConstV(0), ConstV(1)));
894 else if (OPTS_OPTIMIZATION(OPTIM_VECTOR_COMPONENTS) && CanConstFold1(exprs[0])) {
895 vector vec = ConstV(0);
896 if (!vec.y && !vec.z) { /* 'n 0 0' * v */
897 ++opts_optimizationcount[OPTIM_VECTOR_COMPONENTS];
898 out = (ast_expression*)ast_member_new(ctx, exprs[1], 0, NULL);
899 out->node.keep = false;
900 ((ast_member*)out)->rvalue = true;
902 out = (ast_expression*)ast_binary_new(ctx, INSTR_MUL_F, (ast_expression*)parser_const_float(parser, vec.x), out);
904 else if (!vec.x && !vec.z) { /* '0 n 0' * v */
905 ++opts_optimizationcount[OPTIM_VECTOR_COMPONENTS];
906 out = (ast_expression*)ast_member_new(ctx, exprs[1], 1, NULL);
907 out->node.keep = false;
908 ((ast_member*)out)->rvalue = true;
910 out = (ast_expression*)ast_binary_new(ctx, INSTR_MUL_F, (ast_expression*)parser_const_float(parser, vec.y), out);
912 else if (!vec.x && !vec.y) { /* '0 n 0' * v */
913 ++opts_optimizationcount[OPTIM_VECTOR_COMPONENTS];
914 out = (ast_expression*)ast_member_new(ctx, exprs[1], 2, NULL);
915 out->node.keep = false;
916 ((ast_member*)out)->rvalue = true;
918 out = (ast_expression*)ast_binary_new(ctx, INSTR_MUL_F, (ast_expression*)parser_const_float(parser, vec.z), out);
921 out = (ast_expression*)ast_binary_new(ctx, INSTR_MUL_V, exprs[0], exprs[1]);
923 else if (OPTS_OPTIMIZATION(OPTIM_VECTOR_COMPONENTS) && CanConstFold1(exprs[1])) {
924 vector vec = ConstV(1);
925 if (!vec.y && !vec.z) { /* v * 'n 0 0' */
926 ++opts_optimizationcount[OPTIM_VECTOR_COMPONENTS];
927 out = (ast_expression*)ast_member_new(ctx, exprs[0], 0, NULL);
928 out->node.keep = false;
929 ((ast_member*)out)->rvalue = true;
931 out = (ast_expression*)ast_binary_new(ctx, INSTR_MUL_F, out, (ast_expression*)parser_const_float(parser, vec.x));
933 else if (!vec.x && !vec.z) { /* v * '0 n 0' */
934 ++opts_optimizationcount[OPTIM_VECTOR_COMPONENTS];
935 out = (ast_expression*)ast_member_new(ctx, exprs[0], 1, NULL);
936 out->node.keep = false;
937 ((ast_member*)out)->rvalue = true;
939 out = (ast_expression*)ast_binary_new(ctx, INSTR_MUL_F, out, (ast_expression*)parser_const_float(parser, vec.y));
941 else if (!vec.x && !vec.y) { /* v * '0 n 0' */
942 ++opts_optimizationcount[OPTIM_VECTOR_COMPONENTS];
943 out = (ast_expression*)ast_member_new(ctx, exprs[0], 2, NULL);
944 out->node.keep = false;
945 ((ast_member*)out)->rvalue = true;
947 out = (ast_expression*)ast_binary_new(ctx, INSTR_MUL_F, out, (ast_expression*)parser_const_float(parser, vec.z));
950 out = (ast_expression*)ast_binary_new(ctx, INSTR_MUL_V, exprs[0], exprs[1]);
953 out = (ast_expression*)ast_binary_new(ctx, INSTR_MUL_V, exprs[0], exprs[1]);
957 compile_error(ctx, "invalid types used in expression: cannot multiply types %s and %s",
958 type_name[exprs[1]->vtype],
959 type_name[exprs[0]->vtype]);
964 if (exprs[1]->vtype != TYPE_FLOAT) {
965 ast_type_to_string(exprs[0], ty1, sizeof(ty1));
966 ast_type_to_string(exprs[1], ty2, sizeof(ty2));
967 compile_error(ctx, "invalid types used in expression: cannot divide tyeps %s and %s", ty1, ty2);
970 if (exprs[0]->vtype == TYPE_FLOAT) {
971 if (CanConstFold(exprs[0], exprs[1]))
972 out = (ast_expression*)parser_const_float(parser, ConstF(0) / ConstF(1));
974 out = (ast_expression*)ast_binary_new(ctx, INSTR_DIV_F, exprs[0], exprs[1]);
976 else if (exprs[0]->vtype == TYPE_VECTOR) {
977 if (CanConstFold(exprs[0], exprs[1]))
978 out = (ast_expression*)parser_const_vector(parser, vec3_mulvf(ConstV(0), 1.0/ConstF(1)));
980 if (CanConstFold1(exprs[1])) {
981 out = (ast_expression*)parser_const_float(parser, 1.0 / ConstF(1));
983 out = (ast_expression*)ast_binary_new(ctx, INSTR_DIV_F,
984 (ast_expression*)parser_const_float_1(parser),
988 compile_error(ctx, "internal error: failed to generate division");
991 out = (ast_expression*)ast_binary_new(ctx, INSTR_MUL_VF, exprs[0], out);
996 ast_type_to_string(exprs[0], ty1, sizeof(ty1));
997 ast_type_to_string(exprs[1], ty2, sizeof(ty2));
998 compile_error(ctx, "invalid types used in expression: cannot divide tyeps %s and %s", ty1, ty2);
1004 if (NotSameType(TYPE_FLOAT)) {
1005 compile_error(ctx, "invalid types used in expression: cannot perform modulo operation between types %s and %s",
1006 type_name[exprs[0]->vtype],
1007 type_name[exprs[1]->vtype]);
1010 if (CanConstFold(exprs[0], exprs[1])) {
1011 out = (ast_expression*)parser_const_float(parser,
1012 (float)(((qcint)ConstF(0)) % ((qcint)ConstF(1))));
1014 /* generate a call to __builtin_mod */
1015 ast_expression *mod = intrin_func(parser, "mod");
1016 ast_call *call = NULL;
1017 if (!mod) return false; /* can return null for missing floor */
1019 call = ast_call_new(parser_ctx(parser), mod);
1020 vec_push(call->params, exprs[0]);
1021 vec_push(call->params, exprs[1]);
1023 out = (ast_expression*)call;
1027 case opid2('%','='):
1028 compile_error(ctx, "%= is unimplemented");
1033 if (NotSameType(TYPE_FLOAT)) {
1034 compile_error(ctx, "invalid types used in expression: cannot perform bit operations between types %s and %s",
1035 type_name[exprs[0]->vtype],
1036 type_name[exprs[1]->vtype]);
1039 if (CanConstFold(exprs[0], exprs[1]))
1040 out = (ast_expression*)parser_const_float(parser,
1041 (op->id == opid1('|') ? (float)( ((qcint)ConstF(0)) | ((qcint)ConstF(1)) ) :
1042 (float)( ((qcint)ConstF(0)) & ((qcint)ConstF(1)) ) ));
1044 out = (ast_expression*)ast_binary_new(ctx,
1045 (op->id == opid1('|') ? INSTR_BITOR : INSTR_BITAND),
1046 exprs[0], exprs[1]);
1049 compile_error(ast_ctx(exprs[0]), "Not Yet Implemented: bit-xor via ^");
1052 case opid2('<','<'):
1053 case opid2('>','>'):
1054 if (CanConstFold(exprs[0], exprs[1]) && ! NotSameType(TYPE_FLOAT)) {
1055 if (op->id == opid2('<','<'))
1056 out = (ast_expression*)parser_const_float(parser, (double)((unsigned int)(ConstF(0)) << (unsigned int)(ConstF(1))));
1058 out = (ast_expression*)parser_const_float(parser, (double)((unsigned int)(ConstF(0)) >> (unsigned int)(ConstF(1))));
1061 case opid3('<','<','='):
1062 case opid3('>','>','='):
1063 compile_error(ast_ctx(exprs[0]), "Not Yet Implemented: bit-shifts");
1066 case opid2('|','|'):
1067 generated_op += 1; /* INSTR_OR */
1068 case opid2('&','&'):
1069 generated_op += INSTR_AND;
1070 if (CanConstFold(exprs[0], exprs[1]))
1072 if (OPTS_FLAG(PERL_LOGIC)) {
1073 if (immediate_is_true(ctx, asvalue[0]))
1077 out = (ast_expression*)parser_const_float(parser,
1078 ( (generated_op == INSTR_OR)
1079 ? (immediate_is_true(ctx, asvalue[0]) || immediate_is_true(ctx, asvalue[1]))
1080 : (immediate_is_true(ctx, asvalue[0]) && immediate_is_true(ctx, asvalue[1])) )
1085 if (OPTS_FLAG(PERL_LOGIC) && !ast_compare_type(exprs[0], exprs[1])) {
1086 ast_type_to_string(exprs[0], ty1, sizeof(ty1));
1087 ast_type_to_string(exprs[1], ty2, sizeof(ty2));
1088 compile_error(ctx, "invalid types for logical operation with -fperl-logic: %s and %s", ty1, ty2);
1091 for (i = 0; i < 2; ++i) {
1092 if (OPTS_FLAG(CORRECT_LOGIC) && exprs[i]->vtype == TYPE_VECTOR) {
1093 out = (ast_expression*)ast_unary_new(ctx, INSTR_NOT_V, exprs[i]);
1095 out = (ast_expression*)ast_unary_new(ctx, INSTR_NOT_F, out);
1097 exprs[i] = out; out = NULL;
1098 if (OPTS_FLAG(PERL_LOGIC)) {
1099 /* here we want to keep the right expressions' type */
1103 else if (OPTS_FLAG(FALSE_EMPTY_STRINGS) && exprs[i]->vtype == TYPE_STRING) {
1104 out = (ast_expression*)ast_unary_new(ctx, INSTR_NOT_S, exprs[i]);
1106 out = (ast_expression*)ast_unary_new(ctx, INSTR_NOT_F, out);
1108 exprs[i] = out; out = NULL;
1109 if (OPTS_FLAG(PERL_LOGIC)) {
1110 /* here we want to keep the right expressions' type */
1115 out = (ast_expression*)ast_binary_new(ctx, generated_op, exprs[0], exprs[1]);
1119 case opid2('?',':'):
1120 if (vec_last(sy->paren) != PAREN_TERNARY2) {
1121 compile_error(ctx, "mismatched parenthesis/ternary");
1125 if (!ast_compare_type(exprs[1], exprs[2])) {
1126 ast_type_to_string(exprs[1], ty1, sizeof(ty1));
1127 ast_type_to_string(exprs[2], ty2, sizeof(ty2));
1128 compile_error(ctx, "operands of ternary expression must have the same type, got %s and %s", ty1, ty2);
1131 if (CanConstFold1(exprs[0]))
1132 out = (immediate_is_true(ctx, asvalue[0]) ? exprs[1] : exprs[2]);
1134 out = (ast_expression*)ast_ternary_new(ctx, exprs[0], exprs[1], exprs[2]);
1137 case opid2('*', '*'):
1138 if (NotSameType(TYPE_FLOAT)) {
1139 ast_type_to_string(exprs[0], ty1, sizeof(ty1));
1140 ast_type_to_string(exprs[1], ty2, sizeof(ty2));
1141 compile_error(ctx, "invalid types used in exponentiation: %s and %s",
1147 if (CanConstFold(exprs[0], exprs[1])) {
1148 out = (ast_expression*)parser_const_float(parser, powf(ConstF(0), ConstF(1)));
1150 ast_call *gencall = ast_call_new(parser_ctx(parser), intrin_func(parser, "pow"));
1151 vec_push(gencall->params, exprs[0]);
1152 vec_push(gencall->params, exprs[1]);
1153 out = (ast_expression*)gencall;
1157 case opid3('<','=','>'): /* -1, 0, or 1 */
1158 if (NotSameType(TYPE_FLOAT)) {
1159 ast_type_to_string(exprs[0], ty1, sizeof(ty1));
1160 ast_type_to_string(exprs[1], ty2, sizeof(ty2));
1161 compile_error(ctx, "invalid types used in comparision: %s and %s",
1167 if (CanConstFold(exprs[0], exprs[1])) {
1168 if (ConstF(0) < ConstF(1))
1169 out = (ast_expression*)parser_const_float_neg1(parser);
1170 else if (ConstF(0) == ConstF(1))
1171 out = (ast_expression*)parser_const_float_0(parser);
1172 else if (ConstF(0) > ConstF(1))
1173 out = (ast_expression*)parser_const_float_1(parser);
1175 ast_binary *eq = ast_binary_new(ctx, INSTR_EQ_F, exprs[0], exprs[1]);
1177 eq->refs = (ast_binary_ref)false; /* references nothing */
1180 out = (ast_expression*)ast_ternary_new(ctx,
1181 (ast_expression*)ast_binary_new(ctx, INSTR_LT, exprs[0], exprs[1]),
1183 (ast_expression*)parser_const_float_neg1(parser),
1186 (ast_expression*)ast_ternary_new(ctx, (ast_expression*)eq,
1188 (ast_expression*)parser_const_float_0(parser),
1191 (ast_expression*)parser_const_float_1(parser)
1201 generated_op += 1; /* INSTR_GT */
1203 generated_op += 1; /* INSTR_LT */
1204 case opid2('>', '='):
1205 generated_op += 1; /* INSTR_GE */
1206 case opid2('<', '='):
1207 generated_op += INSTR_LE;
1208 if (NotSameType(TYPE_FLOAT)) {
1209 compile_error(ctx, "invalid types used in expression: cannot perform comparison between types %s and %s",
1210 type_name[exprs[0]->vtype],
1211 type_name[exprs[1]->vtype]);
1214 out = (ast_expression*)ast_binary_new(ctx, generated_op, exprs[0], exprs[1]);
1216 case opid2('!', '='):
1217 if (exprs[0]->vtype != exprs[1]->vtype) {
1218 compile_error(ctx, "invalid types used in expression: cannot perform comparison between types %s and %s",
1219 type_name[exprs[0]->vtype],
1220 type_name[exprs[1]->vtype]);
1223 out = (ast_expression*)ast_binary_new(ctx, type_ne_instr[exprs[0]->vtype], exprs[0], exprs[1]);
1225 case opid2('=', '='):
1226 if (exprs[0]->vtype != exprs[1]->vtype) {
1227 compile_error(ctx, "invalid types used in expression: cannot perform comparison between types %s and %s",
1228 type_name[exprs[0]->vtype],
1229 type_name[exprs[1]->vtype]);
1232 out = (ast_expression*)ast_binary_new(ctx, type_eq_instr[exprs[0]->vtype], exprs[0], exprs[1]);
1236 if (ast_istype(exprs[0], ast_entfield)) {
1237 ast_expression *field = ((ast_entfield*)exprs[0])->field;
1238 if (OPTS_FLAG(ADJUST_VECTOR_FIELDS) &&
1239 exprs[0]->vtype == TYPE_FIELD &&
1240 exprs[0]->next->vtype == TYPE_VECTOR)
1242 assignop = type_storep_instr[TYPE_VECTOR];
1245 assignop = type_storep_instr[exprs[0]->vtype];
1246 if (assignop == VINSTR_END || !ast_compare_type(field->next, exprs[1]))
1248 ast_type_to_string(field->next, ty1, sizeof(ty1));
1249 ast_type_to_string(exprs[1], ty2, sizeof(ty2));
1250 if (OPTS_FLAG(ASSIGN_FUNCTION_TYPES) &&
1251 field->next->vtype == TYPE_FUNCTION &&
1252 exprs[1]->vtype == TYPE_FUNCTION)
1254 (void)!compile_warning(ctx, WARN_ASSIGN_FUNCTION_TYPES,
1255 "invalid types in assignment: cannot assign %s to %s", ty2, ty1);
1258 compile_error(ctx, "invalid types in assignment: cannot assign %s to %s", ty2, ty1);
1264 if (OPTS_FLAG(ADJUST_VECTOR_FIELDS) &&
1265 exprs[0]->vtype == TYPE_FIELD &&
1266 exprs[0]->next->vtype == TYPE_VECTOR)
1268 assignop = type_store_instr[TYPE_VECTOR];
1271 assignop = type_store_instr[exprs[0]->vtype];
1274 if (assignop == VINSTR_END) {
1275 ast_type_to_string(exprs[0], ty1, sizeof(ty1));
1276 ast_type_to_string(exprs[1], ty2, sizeof(ty2));
1277 compile_error(ctx, "invalid types in assignment: cannot assign %s to %s", ty2, ty1);
1279 else if (!ast_compare_type(exprs[0], exprs[1]))
1281 ast_type_to_string(exprs[0], ty1, sizeof(ty1));
1282 ast_type_to_string(exprs[1], ty2, sizeof(ty2));
1283 if (OPTS_FLAG(ASSIGN_FUNCTION_TYPES) &&
1284 exprs[0]->vtype == TYPE_FUNCTION &&
1285 exprs[1]->vtype == TYPE_FUNCTION)
1287 (void)!compile_warning(ctx, WARN_ASSIGN_FUNCTION_TYPES,
1288 "invalid types in assignment: cannot assign %s to %s", ty2, ty1);
1291 compile_error(ctx, "invalid types in assignment: cannot assign %s to %s", ty2, ty1);
1294 if (ast_istype(exprs[0], ast_value) && asvalue[0]->cvq == CV_CONST) {
1295 compile_error(ctx, "assignment to constant `%s`", asvalue[0]->name);
1297 out = (ast_expression*)ast_store_new(ctx, assignop, exprs[0], exprs[1]);
1299 case opid3('+','+','P'):
1300 case opid3('-','-','P'):
1302 if (exprs[0]->vtype != TYPE_FLOAT) {
1303 ast_type_to_string(exprs[0], ty1, sizeof(ty1));
1304 compile_error(ast_ctx(exprs[0]), "invalid type for prefix increment: %s", ty1);
1307 if (op->id == opid3('+','+','P'))
1308 addop = INSTR_ADD_F;
1310 addop = INSTR_SUB_F;
1311 if (ast_istype(exprs[0], ast_value) && asvalue[0]->cvq == CV_CONST) {
1312 compile_error(ast_ctx(exprs[0]), "assignment to constant `%s`", asvalue[0]->name);
1314 if (ast_istype(exprs[0], ast_entfield)) {
1315 out = (ast_expression*)ast_binstore_new(ctx, INSTR_STOREP_F, addop,
1317 (ast_expression*)parser_const_float_1(parser));
1319 out = (ast_expression*)ast_binstore_new(ctx, INSTR_STORE_F, addop,
1321 (ast_expression*)parser_const_float_1(parser));
1324 case opid3('S','+','+'):
1325 case opid3('S','-','-'):
1327 if (exprs[0]->vtype != TYPE_FLOAT) {
1328 ast_type_to_string(exprs[0], ty1, sizeof(ty1));
1329 compile_error(ast_ctx(exprs[0]), "invalid type for suffix increment: %s", ty1);
1332 if (op->id == opid3('S','+','+')) {
1333 addop = INSTR_ADD_F;
1334 subop = INSTR_SUB_F;
1336 addop = INSTR_SUB_F;
1337 subop = INSTR_ADD_F;
1339 if (ast_istype(exprs[0], ast_value) && asvalue[0]->cvq == CV_CONST) {
1340 compile_error(ast_ctx(exprs[0]), "assignment to constant `%s`", asvalue[0]->name);
1342 if (ast_istype(exprs[0], ast_entfield)) {
1343 out = (ast_expression*)ast_binstore_new(ctx, INSTR_STOREP_F, addop,
1345 (ast_expression*)parser_const_float_1(parser));
1347 out = (ast_expression*)ast_binstore_new(ctx, INSTR_STORE_F, addop,
1349 (ast_expression*)parser_const_float_1(parser));
1353 out = (ast_expression*)ast_binary_new(ctx, subop,
1355 (ast_expression*)parser_const_float_1(parser));
1357 case opid2('+','='):
1358 case opid2('-','='):
1359 if (exprs[0]->vtype != exprs[1]->vtype ||
1360 (exprs[0]->vtype != TYPE_VECTOR && exprs[0]->vtype != TYPE_FLOAT) )
1362 ast_type_to_string(exprs[0], ty1, sizeof(ty1));
1363 ast_type_to_string(exprs[1], ty2, sizeof(ty2));
1364 compile_error(ctx, "invalid types used in expression: cannot add or subtract type %s and %s",
1368 if (ast_istype(exprs[0], ast_value) && asvalue[0]->cvq == CV_CONST) {
1369 compile_error(ctx, "assignment to constant `%s`", asvalue[0]->name);
1371 if (ast_istype(exprs[0], ast_entfield))
1372 assignop = type_storep_instr[exprs[0]->vtype];
1374 assignop = type_store_instr[exprs[0]->vtype];
1375 switch (exprs[0]->vtype) {
1377 out = (ast_expression*)ast_binstore_new(ctx, assignop,
1378 (op->id == opid2('+','=') ? INSTR_ADD_F : INSTR_SUB_F),
1379 exprs[0], exprs[1]);
1382 out = (ast_expression*)ast_binstore_new(ctx, assignop,
1383 (op->id == opid2('+','=') ? INSTR_ADD_V : INSTR_SUB_V),
1384 exprs[0], exprs[1]);
1387 compile_error(ctx, "invalid types used in expression: cannot add or subtract type %s and %s",
1388 type_name[exprs[0]->vtype],
1389 type_name[exprs[1]->vtype]);
1393 case opid2('*','='):
1394 case opid2('/','='):
1395 if (exprs[1]->vtype != TYPE_FLOAT ||
1396 !(exprs[0]->vtype == TYPE_FLOAT ||
1397 exprs[0]->vtype == TYPE_VECTOR))
1399 ast_type_to_string(exprs[0], ty1, sizeof(ty1));
1400 ast_type_to_string(exprs[1], ty2, sizeof(ty2));
1401 compile_error(ctx, "invalid types used in expression: %s and %s",
1405 if (ast_istype(exprs[0], ast_value) && asvalue[0]->cvq == CV_CONST) {
1406 compile_error(ctx, "assignment to constant `%s`", asvalue[0]->name);
1408 if (ast_istype(exprs[0], ast_entfield))
1409 assignop = type_storep_instr[exprs[0]->vtype];
1411 assignop = type_store_instr[exprs[0]->vtype];
1412 switch (exprs[0]->vtype) {
1414 out = (ast_expression*)ast_binstore_new(ctx, assignop,
1415 (op->id == opid2('*','=') ? INSTR_MUL_F : INSTR_DIV_F),
1416 exprs[0], exprs[1]);
1419 if (op->id == opid2('*','=')) {
1420 out = (ast_expression*)ast_binstore_new(ctx, assignop, INSTR_MUL_VF,
1421 exprs[0], exprs[1]);
1423 /* there's no DIV_VF */
1424 if (CanConstFold1(exprs[1])) {
1425 out = (ast_expression*)parser_const_float(parser, 1.0 / ConstF(1));
1427 out = (ast_expression*)ast_binary_new(ctx, INSTR_DIV_F,
1428 (ast_expression*)parser_const_float_1(parser),
1432 compile_error(ctx, "internal error: failed to generate division");
1435 out = (ast_expression*)ast_binstore_new(ctx, assignop, INSTR_MUL_VF,
1440 compile_error(ctx, "invalid types used in expression: cannot add or subtract type %s and %s",
1441 type_name[exprs[0]->vtype],
1442 type_name[exprs[1]->vtype]);
1446 case opid2('&','='):
1447 case opid2('|','='):
1448 if (NotSameType(TYPE_FLOAT)) {
1449 ast_type_to_string(exprs[0], ty1, sizeof(ty1));
1450 ast_type_to_string(exprs[1], ty2, sizeof(ty2));
1451 compile_error(ctx, "invalid types used in expression: %s and %s",
1455 if (ast_istype(exprs[0], ast_value) && asvalue[0]->cvq == CV_CONST) {
1456 compile_error(ctx, "assignment to constant `%s`", asvalue[0]->name);
1458 if (ast_istype(exprs[0], ast_entfield))
1459 assignop = type_storep_instr[exprs[0]->vtype];
1461 assignop = type_store_instr[exprs[0]->vtype];
1462 out = (ast_expression*)ast_binstore_new(ctx, assignop,
1463 (op->id == opid2('&','=') ? INSTR_BITAND : INSTR_BITOR),
1464 exprs[0], exprs[1]);
1466 case opid3('&','~','='):
1467 /* This is like: a &= ~(b);
1468 * But QC has no bitwise-not, so we implement it as
1471 if (NotSameType(TYPE_FLOAT)) {
1472 ast_type_to_string(exprs[0], ty1, sizeof(ty1));
1473 ast_type_to_string(exprs[1], ty2, sizeof(ty2));
1474 compile_error(ctx, "invalid types used in expression: %s and %s",
1478 if (ast_istype(exprs[0], ast_entfield))
1479 assignop = type_storep_instr[exprs[0]->vtype];
1481 assignop = type_store_instr[exprs[0]->vtype];
1482 out = (ast_expression*)ast_binary_new(ctx, INSTR_BITAND, exprs[0], exprs[1]);
1485 if (ast_istype(exprs[0], ast_value) && asvalue[0]->cvq == CV_CONST) {
1486 compile_error(ctx, "assignment to constant `%s`", asvalue[0]->name);
1488 asbinstore = ast_binstore_new(ctx, assignop, INSTR_SUB_F, exprs[0], out);
1489 asbinstore->keep_dest = true;
1490 out = (ast_expression*)asbinstore;
1493 case opid2('~', 'P'):
1494 if (exprs[0]->vtype != TYPE_FLOAT) {
1495 ast_type_to_string(exprs[0], ty1, sizeof(ty1));
1496 compile_error(ast_ctx(exprs[0]), "invalid type for bit not: %s", ty1);
1500 if(CanConstFold1(exprs[0]))
1501 out = (ast_expression*)parser_const_float(parser, ~(qcint)ConstF(0));
1503 out = (ast_expression*)
1504 ast_binary_new(ctx, INSTR_SUB_F, (ast_expression*)parser_const_float_neg1(parser), exprs[0]);
1510 compile_error(ctx, "failed to apply operator %s", op->op);
1514 vec_push(sy->out, syexp(ctx, out));
1518 static bool parser_close_call(parser_t *parser, shunt *sy)
1520 /* was a function call */
1521 ast_expression *fun;
1522 ast_value *funval = NULL;
1526 size_t paramcount, i;
1528 fid = vec_last(sy->ops).off;
1529 vec_shrinkby(sy->ops, 1);
1531 /* out[fid] is the function
1532 * everything above is parameters...
1534 if (!vec_size(sy->argc)) {
1535 parseerror(parser, "internal error: no argument counter available");
1539 paramcount = vec_last(sy->argc);
1542 if (vec_size(sy->out) < fid) {
1543 parseerror(parser, "internal error: broken function call%lu < %lu+%lu\n",
1544 (unsigned long)vec_size(sy->out),
1546 (unsigned long)paramcount);
1550 fun = sy->out[fid].out;
1552 if (fun == intrinsic_debug_typestring) {
1554 if (fid+2 != vec_size(sy->out) ||
1555 vec_last(sy->out).block)
1557 parseerror(parser, "intrinsic __builtin_debug_typestring requires exactly 1 parameter");
1560 ast_type_to_string(vec_last(sy->out).out, ty, sizeof(ty));
1561 ast_unref(vec_last(sy->out).out);
1562 sy->out[fid] = syexp(ast_ctx(vec_last(sy->out).out),
1563 (ast_expression*)parser_const_string(parser, ty, false));
1564 vec_shrinkby(sy->out, 1);
1568 call = ast_call_new(sy->ops[vec_size(sy->ops)].ctx, fun);
1572 if (fid+1 < vec_size(sy->out))
1575 if (fid+1 + paramcount != vec_size(sy->out)) {
1576 parseerror(parser, "internal error: parameter count mismatch: (%lu+1+%lu), %lu",
1577 (unsigned long)fid, (unsigned long)paramcount, (unsigned long)vec_size(sy->out));
1581 for (i = 0; i < paramcount; ++i)
1582 vec_push(call->params, sy->out[fid+1 + i].out);
1583 vec_shrinkby(sy->out, paramcount);
1584 (void)!ast_call_check_types(call);
1585 if (parser->max_param_count < paramcount)
1586 parser->max_param_count = paramcount;
1588 if (ast_istype(fun, ast_value)) {
1589 funval = (ast_value*)fun;
1590 if ((fun->flags & AST_FLAG_VARIADIC) &&
1591 !(/*funval->cvq == CV_CONST && */ funval->hasvalue && funval->constval.vfunc->builtin))
1593 call->va_count = (ast_expression*)parser_const_float(parser, (double)paramcount);
1597 /* overwrite fid, the function, with a call */
1598 sy->out[fid] = syexp(call->expression.node.context, (ast_expression*)call);
1600 if (fun->vtype != TYPE_FUNCTION) {
1601 parseerror(parser, "not a function (%s)", type_name[fun->vtype]);
1606 parseerror(parser, "could not determine function return type");
1609 ast_value *fval = (ast_istype(fun, ast_value) ? ((ast_value*)fun) : NULL);
1611 if (fun->flags & AST_FLAG_DEPRECATED) {
1613 return !parsewarning(parser, WARN_DEPRECATED,
1614 "call to function (which is marked deprecated)\n",
1615 "-> it has been declared here: %s:%i",
1616 ast_ctx(fun).file, ast_ctx(fun).line);
1619 return !parsewarning(parser, WARN_DEPRECATED,
1620 "call to `%s` (which is marked deprecated)\n"
1621 "-> `%s` declared here: %s:%i",
1622 fval->name, fval->name, ast_ctx(fun).file, ast_ctx(fun).line);
1624 return !parsewarning(parser, WARN_DEPRECATED,
1625 "call to `%s` (deprecated: %s)\n"
1626 "-> `%s` declared here: %s:%i",
1627 fval->name, fval->desc, fval->name, ast_ctx(fun).file,
1631 if (vec_size(fun->params) != paramcount &&
1632 !((fun->flags & AST_FLAG_VARIADIC) &&
1633 vec_size(fun->params) < paramcount))
1635 const char *fewmany = (vec_size(fun->params) > paramcount) ? "few" : "many";
1637 return !parsewarning(parser, WARN_INVALID_PARAMETER_COUNT,
1638 "too %s parameters for call to %s: expected %i, got %i\n"
1639 " -> `%s` has been declared here: %s:%i",
1640 fewmany, fval->name, (int)vec_size(fun->params), (int)paramcount,
1641 fval->name, ast_ctx(fun).file, (int)ast_ctx(fun).line);
1643 return !parsewarning(parser, WARN_INVALID_PARAMETER_COUNT,
1644 "too %s parameters for function call: expected %i, got %i\n"
1645 " -> it has been declared here: %s:%i",
1646 fewmany, (int)vec_size(fun->params), (int)paramcount,
1647 ast_ctx(fun).file, (int)ast_ctx(fun).line);
1654 static bool parser_close_paren(parser_t *parser, shunt *sy)
1656 if (!vec_size(sy->ops)) {
1657 parseerror(parser, "unmatched closing paren");
1661 while (vec_size(sy->ops)) {
1662 if (vec_last(sy->ops).isparen) {
1663 if (vec_last(sy->paren) == PAREN_FUNC) {
1665 if (!parser_close_call(parser, sy))
1669 if (vec_last(sy->paren) == PAREN_EXPR) {
1671 if (!vec_size(sy->out)) {
1672 compile_error(vec_last(sy->ops).ctx, "empty paren expression");
1673 vec_shrinkby(sy->ops, 1);
1676 vec_shrinkby(sy->ops, 1);
1679 if (vec_last(sy->paren) == PAREN_INDEX) {
1681 /* pop off the parenthesis */
1682 vec_shrinkby(sy->ops, 1);
1683 /* then apply the index operator */
1684 if (!parser_sy_apply_operator(parser, sy))
1688 if (vec_last(sy->paren) == PAREN_TERNARY1) {
1689 vec_last(sy->paren) = PAREN_TERNARY2;
1690 /* pop off the parenthesis */
1691 vec_shrinkby(sy->ops, 1);
1694 compile_error(vec_last(sy->ops).ctx, "invalid parenthesis");
1697 if (!parser_sy_apply_operator(parser, sy))
1703 static void parser_reclassify_token(parser_t *parser)
1706 if (parser->tok >= TOKEN_START)
1708 for (i = 0; i < operator_count; ++i) {
1709 if (!strcmp(parser_tokval(parser), operators[i].op)) {
1710 parser->tok = TOKEN_OPERATOR;
1716 static ast_expression* parse_vararg_do(parser_t *parser)
1718 ast_expression *idx, *out;
1720 ast_value *funtype = parser->function->vtype;
1722 lex_ctx ctx = parser_ctx(parser);
1724 if (!parser_next(parser) || parser->tok != '(') {
1725 parseerror(parser, "expected parameter index and type in parenthesis");
1728 if (!parser_next(parser)) {
1729 parseerror(parser, "error parsing parameter index");
1733 idx = parse_expression_leave(parser, true, false, false);
1737 if (parser->tok != ',') {
1739 parseerror(parser, "expected comma after parameter index");
1743 if (!parser_next(parser) || (parser->tok != TOKEN_IDENT && parser->tok != TOKEN_TYPENAME)) {
1745 parseerror(parser, "expected typename for vararg");
1749 typevar = parse_typename(parser, NULL, NULL);
1755 if (parser->tok != ')') {
1757 ast_delete(typevar);
1758 parseerror(parser, "expected closing paren");
1763 if (!parser_next(parser)) {
1765 ast_delete(typevar);
1766 parseerror(parser, "parse error after vararg");
1771 if (!parser->function->varargs) {
1773 ast_delete(typevar);
1774 parseerror(parser, "function has no variable argument list");
1778 if (funtype->expression.varparam &&
1779 !ast_compare_type((ast_expression*)typevar, (ast_expression*)funtype->expression.varparam))
1783 ast_type_to_string((ast_expression*)typevar, ty1, sizeof(ty1));
1784 ast_type_to_string((ast_expression*)funtype->expression.varparam, ty2, sizeof(ty2));
1785 compile_error(ast_ctx(typevar),
1786 "function was declared to take varargs of type `%s`, requested type is: %s",
1790 out = (ast_expression*)ast_array_index_new(ctx, (ast_expression*)(parser->function->varargs), idx);
1791 ast_type_adopt(out, typevar);
1792 ast_delete(typevar);
1796 static ast_expression* parse_vararg(parser_t *parser)
1798 bool old_noops = parser->lex->flags.noops;
1800 ast_expression *out;
1802 parser->lex->flags.noops = true;
1803 out = parse_vararg_do(parser);
1805 parser->lex->flags.noops = old_noops;
1809 /* not to be exposed */
1810 extern bool ftepp_predef_exists(const char *name);
1812 static bool parse_sya_operand(parser_t *parser, shunt *sy, bool with_labels)
1814 if (OPTS_FLAG(TRANSLATABLE_STRINGS) &&
1815 parser->tok == TOKEN_IDENT &&
1816 !strcmp(parser_tokval(parser), "_"))
1818 /* a translatable string */
1821 parser->lex->flags.noops = true;
1822 if (!parser_next(parser) || parser->tok != '(') {
1823 parseerror(parser, "use _(\"string\") to create a translatable string constant");
1826 parser->lex->flags.noops = false;
1827 if (!parser_next(parser) || parser->tok != TOKEN_STRINGCONST) {
1828 parseerror(parser, "expected a constant string in translatable-string extension");
1831 val = parser_const_string(parser, parser_tokval(parser), true);
1834 vec_push(sy->out, syexp(parser_ctx(parser), (ast_expression*)val));
1836 if (!parser_next(parser) || parser->tok != ')') {
1837 parseerror(parser, "expected closing paren after translatable string");
1842 else if (parser->tok == TOKEN_DOTS)
1845 if (!OPTS_FLAG(VARIADIC_ARGS)) {
1846 parseerror(parser, "cannot access varargs (try -fvariadic-args)");
1849 va = parse_vararg(parser);
1852 vec_push(sy->out, syexp(parser_ctx(parser), va));
1855 else if (parser->tok == TOKEN_FLOATCONST) {
1857 val = parser_const_float(parser, (parser_token(parser)->constval.f));
1860 vec_push(sy->out, syexp(parser_ctx(parser), (ast_expression*)val));
1863 else if (parser->tok == TOKEN_INTCONST || parser->tok == TOKEN_CHARCONST) {
1865 val = parser_const_float(parser, (double)(parser_token(parser)->constval.i));
1868 vec_push(sy->out, syexp(parser_ctx(parser), (ast_expression*)val));
1871 else if (parser->tok == TOKEN_STRINGCONST) {
1873 val = parser_const_string(parser, parser_tokval(parser), false);
1876 vec_push(sy->out, syexp(parser_ctx(parser), (ast_expression*)val));
1879 else if (parser->tok == TOKEN_VECTORCONST) {
1881 val = parser_const_vector(parser, parser_token(parser)->constval.v);
1884 vec_push(sy->out, syexp(parser_ctx(parser), (ast_expression*)val));
1887 else if (parser->tok == TOKEN_IDENT)
1889 const char *ctoken = parser_tokval(parser);
1890 ast_expression *prev = vec_size(sy->out) ? vec_last(sy->out).out : NULL;
1891 ast_expression *var;
1892 /* a_vector.{x,y,z} */
1893 if (!vec_size(sy->ops) ||
1894 !vec_last(sy->ops).etype ||
1895 operators[vec_last(sy->ops).etype-1].id != opid1('.') ||
1896 (prev >= intrinsic_debug_typestring &&
1897 prev <= intrinsic_debug_typestring))
1899 /* When adding more intrinsics, fix the above condition */
1902 if (prev && prev->vtype == TYPE_VECTOR && ctoken[0] >= 'x' && ctoken[0] <= 'z' && !ctoken[1])
1904 var = (ast_expression*)parser->const_vec[ctoken[0]-'x'];
1906 var = parser_find_var(parser, parser_tokval(parser));
1908 var = parser_find_field(parser, parser_tokval(parser));
1910 if (!var && with_labels) {
1911 var = (ast_expression*)parser_find_label(parser, parser_tokval(parser));
1913 ast_label *lbl = ast_label_new(parser_ctx(parser), parser_tokval(parser), true);
1914 var = (ast_expression*)lbl;
1915 vec_push(parser->labels, lbl);
1918 if (!var && !strcmp(parser_tokval(parser), "__FUNC__"))
1919 var = (ast_expression*)parser_const_string(parser, parser->function->name, false);
1922 if (!strcmp(parser_tokval(parser), "__builtin_debug_typestring")) {
1923 var = (ast_expression*)intrinsic_debug_typestring;
1925 /* now we try for the real intrinsic hashtable. If the string
1926 * begins with __builtin, we simply skip past it, otherwise we
1927 * use the identifier as is.
1929 else if (!strncmp(parser_tokval(parser), "__builtin_", 10)) {
1930 var = intrin_func(parser, parser_tokval(parser) + 10 /* skip __builtin */);
1934 char *correct = NULL;
1938 * sometimes people use preprocessing predefs without enabling them
1939 * i've done this thousands of times already myself. Lets check for
1940 * it in the predef table. And diagnose it better :)
1942 if (!OPTS_FLAG(FTEPP_PREDEFS) && ftepp_predef_exists(parser_tokval(parser))) {
1943 parseerror(parser, "unexpected ident: %s (use -fftepp-predef to enable pre-defined macros)", parser_tokval(parser));
1948 * TODO: determine the best score for the identifier: be it
1949 * a variable, a field.
1951 * We should also consider adding correction tables for
1952 * other things as well.
1954 if (OPTS_OPTION_BOOL(OPTION_CORRECTION) && strlen(parser_tokval(parser)) <= 16) {
1956 correct_init(&corr);
1958 for (i = 0; i < vec_size(parser->correct_variables); i++) {
1959 correct = correct_str(&corr, parser->correct_variables[i], parser_tokval(parser));
1960 if (strcmp(correct, parser_tokval(parser))) {
1962 } else if (correct) {
1967 correct_free(&corr);
1970 parser->diagnostic = DIAGNOSTIC_UNEXPECTED_IDENT;
1971 parseerror(parser, "unexpected ident: %s (did you mean %s?)", parser_tokval(parser), correct);
1976 parser->diagnostic = DIAGNOSTIC_UNEXPECTED_IDENT;
1977 parseerror(parser, "unexpected ident: %s", parser_tokval(parser));
1983 if (ast_istype(var, ast_value)) {
1984 ((ast_value*)var)->uses++;
1986 else if (ast_istype(var, ast_member)) {
1987 ast_member *mem = (ast_member*)var;
1988 if (ast_istype(mem->owner, ast_value))
1989 ((ast_value*)(mem->owner))->uses++;
1992 vec_push(sy->out, syexp(parser_ctx(parser), var));
1995 parser->diagnostic = DIAGNOSTIC_UNEXPECTED_TOKEN;
1996 parseerror(parser, "unexpected token: `%s`", parser_tokval(parser));
2000 static ast_expression* parse_expression_leave(parser_t *parser, bool stopatcomma, bool truthvalue, bool with_labels)
2002 ast_expression *expr = NULL;
2005 bool wantop = false;
2006 /* only warn once about an assignment in a truth value because the current code
2007 * would trigger twice on: if(a = b && ...), once for the if-truth-value, once for the && part
2009 bool warn_truthvalue = true;
2011 /* count the parens because an if starts with one, so the
2012 * end of a condition is an unmatched closing paren
2016 memset(&sy, 0, sizeof(sy));
2018 parser->lex->flags.noops = false;
2020 parser_reclassify_token(parser);
2024 if (parser->tok == TOKEN_TYPENAME) {
2025 parseerror(parser, "unexpected typename");
2029 if (parser->tok == TOKEN_OPERATOR)
2031 /* classify the operator */
2032 const oper_info *op;
2033 const oper_info *olast = NULL;
2035 for (o = 0; o < operator_count; ++o) {
2036 if (((!(operators[o].flags & OP_PREFIX) == !!wantop)) &&
2037 /* !(operators[o].flags & OP_SUFFIX) && / * remove this */
2038 !strcmp(parser_tokval(parser), operators[o].op))
2043 if (o == operator_count) {
2044 compile_error(parser_ctx(parser), "unknown operator: %s", parser_tokval(parser));
2047 /* found an operator */
2050 /* when declaring variables, a comma starts a new variable */
2051 if (op->id == opid1(',') && !vec_size(sy.paren) && stopatcomma) {
2052 /* fixup the token */
2057 /* a colon without a pervious question mark cannot be a ternary */
2058 if (!ternaries && op->id == opid2(':','?')) {
2063 if (op->id == opid1(',')) {
2064 if (vec_size(sy.paren) && vec_last(sy.paren) == PAREN_TERNARY2) {
2065 (void)!parsewarning(parser, WARN_TERNARY_PRECEDENCE, "suggesting parenthesis around ternary expression");
2069 if (vec_size(sy.ops) && !vec_last(sy.ops).isparen)
2070 olast = &operators[vec_last(sy.ops).etype-1];
2072 #define IsAssignOp(x) (\
2073 (x) == opid1('=') || \
2074 (x) == opid2('+','=') || \
2075 (x) == opid2('-','=') || \
2076 (x) == opid2('*','=') || \
2077 (x) == opid2('/','=') || \
2078 (x) == opid2('%','=') || \
2079 (x) == opid2('&','=') || \
2080 (x) == opid2('|','=') || \
2081 (x) == opid3('&','~','=') \
2083 if (warn_truthvalue) {
2084 if ( (olast && IsAssignOp(olast->id) && (op->id == opid2('&','&') || op->id == opid2('|','|'))) ||
2085 (olast && IsAssignOp(op->id) && (olast->id == opid2('&','&') || olast->id == opid2('|','|'))) ||
2086 (truthvalue && !vec_size(sy.paren) && IsAssignOp(op->id))
2089 (void)!parsewarning(parser, WARN_PARENTHESIS, "suggesting parenthesis around assignment used as truth value");
2090 warn_truthvalue = false;
2095 (op->prec < olast->prec) ||
2096 (op->assoc == ASSOC_LEFT && op->prec <= olast->prec) ) )
2098 if (!parser_sy_apply_operator(parser, &sy))
2100 if (vec_size(sy.ops) && !vec_last(sy.ops).isparen)
2101 olast = &operators[vec_last(sy.ops).etype-1];
2106 if (op->id == opid1('(')) {
2108 size_t sycount = vec_size(sy.out);
2109 /* we expected an operator, this is the function-call operator */
2110 vec_push(sy.paren, PAREN_FUNC);
2111 vec_push(sy.ops, syparen(parser_ctx(parser), sycount-1));
2112 vec_push(sy.argc, 0);
2114 vec_push(sy.paren, PAREN_EXPR);
2115 vec_push(sy.ops, syparen(parser_ctx(parser), 0));
2118 } else if (op->id == opid1('[')) {
2120 parseerror(parser, "unexpected array subscript");
2123 vec_push(sy.paren, PAREN_INDEX);
2124 /* push both the operator and the paren, this makes life easier */
2125 vec_push(sy.ops, syop(parser_ctx(parser), op));
2126 vec_push(sy.ops, syparen(parser_ctx(parser), 0));
2128 } else if (op->id == opid2('?',':')) {
2129 vec_push(sy.ops, syop(parser_ctx(parser), op));
2130 vec_push(sy.ops, syparen(parser_ctx(parser), 0));
2133 vec_push(sy.paren, PAREN_TERNARY1);
2134 } else if (op->id == opid2(':','?')) {
2135 if (!vec_size(sy.paren)) {
2136 parseerror(parser, "unexpected colon outside ternary expression (missing parenthesis?)");
2139 if (vec_last(sy.paren) != PAREN_TERNARY1) {
2140 parseerror(parser, "unexpected colon outside ternary expression (missing parenthesis?)");
2143 if (!parser_close_paren(parser, &sy))
2145 vec_push(sy.ops, syop(parser_ctx(parser), op));
2149 vec_push(sy.ops, syop(parser_ctx(parser), op));
2150 wantop = !!(op->flags & OP_SUFFIX);
2153 else if (parser->tok == ')') {
2154 while (vec_size(sy.paren) && vec_last(sy.paren) == PAREN_TERNARY2) {
2155 if (!parser_sy_apply_operator(parser, &sy))
2158 if (!vec_size(sy.paren))
2161 if (vec_last(sy.paren) == PAREN_TERNARY1) {
2162 parseerror(parser, "mismatched parentheses (closing paren in ternary expression?)");
2165 if (!parser_close_paren(parser, &sy))
2168 /* must be a function call without parameters */
2169 if (vec_last(sy.paren) != PAREN_FUNC) {
2170 parseerror(parser, "closing paren in invalid position");
2173 if (!parser_close_paren(parser, &sy))
2178 else if (parser->tok == '(') {
2179 parseerror(parser, "internal error: '(' should be classified as operator");
2182 else if (parser->tok == '[') {
2183 parseerror(parser, "internal error: '[' should be classified as operator");
2186 else if (parser->tok == ']') {
2187 while (vec_size(sy.paren) && vec_last(sy.paren) == PAREN_TERNARY2) {
2188 if (!parser_sy_apply_operator(parser, &sy))
2191 if (!vec_size(sy.paren))
2193 if (vec_last(sy.paren) != PAREN_INDEX) {
2194 parseerror(parser, "mismatched parentheses, unexpected ']'");
2197 if (!parser_close_paren(parser, &sy))
2202 if (!parse_sya_operand(parser, &sy, with_labels))
2205 if (vec_size(sy.paren) && vec_last(sy.ops).isparen && vec_last(sy.paren) == PAREN_FUNC)
2206 vec_last(sy.argc)++;
2211 /* in this case we might want to allow constant string concatenation */
2212 bool concatenated = false;
2213 if (parser->tok == TOKEN_STRINGCONST && vec_size(sy.out)) {
2214 ast_expression *lexpr = vec_last(sy.out).out;
2215 if (ast_istype(lexpr, ast_value)) {
2216 ast_value *last = (ast_value*)lexpr;
2217 if (last->isimm == true && last->cvq == CV_CONST &&
2218 last->hasvalue && last->expression.vtype == TYPE_STRING)
2220 char *newstr = NULL;
2221 util_asprintf(&newstr, "%s%s", last->constval.vstring, parser_tokval(parser));
2222 vec_last(sy.out).out = (ast_expression*)parser_const_string(parser, newstr, false);
2224 concatenated = true;
2228 if (!concatenated) {
2229 parser->diagnostic = DIAGNOSTIC_EXPECTED_END;
2230 parseerror(parser, "expected operator or end of statement");
2235 if (!parser_next(parser)) {
2238 if (parser->tok == ';' ||
2239 ((!vec_size(sy.paren) || (vec_size(sy.paren) == 1 && vec_last(sy.paren) == PAREN_TERNARY2)) &&
2240 (parser->tok == ']' || parser->tok == ')' || parser->tok == '}')))
2246 while (vec_size(sy.ops)) {
2247 if (!parser_sy_apply_operator(parser, &sy))
2251 parser->lex->flags.noops = true;
2252 if (vec_size(sy.out) != 1) {
2253 parseerror(parser, "expression with not 1 but %lu output values...", (unsigned long) vec_size(sy.out));
2256 expr = sy.out[0].out;
2259 if (vec_size(sy.paren)) {
2260 parseerror(parser, "internal error: vec_size(sy.paren) = %lu", (unsigned long)vec_size(sy.paren));
2268 parser->lex->flags.noops = true;
2269 for (i = 0; i < vec_size(sy.out); ++i) {
2271 ast_unref(sy.out[i].out);
2280 static ast_expression* parse_expression(parser_t *parser, bool stopatcomma, bool with_labels)
2282 ast_expression *e = parse_expression_leave(parser, stopatcomma, false, with_labels);
2285 if (parser->tok != ';') {
2286 parser->diagnostic = DIAGNOSTIC_SEMICOLON;
2287 parseerror(parser, "semicolon expected after expression");
2291 if (!parser_next(parser)) {
2298 static void parser_enterblock(parser_t *parser)
2300 vec_push(parser->variables, util_htnew(PARSER_HT_SIZE));
2301 vec_push(parser->_blocklocals, vec_size(parser->_locals));
2302 vec_push(parser->typedefs, util_htnew(TYPEDEF_HT_SIZE));
2303 vec_push(parser->_blocktypedefs, vec_size(parser->_typedefs));
2304 vec_push(parser->_block_ctx, parser_ctx(parser));
2307 vec_push(parser->correct_variables, correct_trie_new());
2308 vec_push(parser->correct_variables_score, NULL);
2311 static bool parser_leaveblock(parser_t *parser)
2314 size_t locals, typedefs;
2316 if (vec_size(parser->variables) <= PARSER_HT_LOCALS) {
2317 parseerror(parser, "internal error: parser_leaveblock with no block");
2321 util_htdel(vec_last(parser->variables));
2322 correct_del(vec_last(parser->correct_variables), vec_last(parser->correct_variables_score));
2324 vec_pop(parser->variables);
2325 vec_pop(parser->correct_variables);
2326 vec_pop(parser->correct_variables_score);
2327 if (!vec_size(parser->_blocklocals)) {
2328 parseerror(parser, "internal error: parser_leaveblock with no block (2)");
2332 locals = vec_last(parser->_blocklocals);
2333 vec_pop(parser->_blocklocals);
2334 while (vec_size(parser->_locals) != locals) {
2335 ast_expression *e = vec_last(parser->_locals);
2336 ast_value *v = (ast_value*)e;
2337 vec_pop(parser->_locals);
2338 if (ast_istype(e, ast_value) && !v->uses) {
2339 if (compile_warning(ast_ctx(v), WARN_UNUSED_VARIABLE, "unused variable: `%s`", v->name))
2344 typedefs = vec_last(parser->_blocktypedefs);
2345 while (vec_size(parser->_typedefs) != typedefs) {
2346 ast_delete(vec_last(parser->_typedefs));
2347 vec_pop(parser->_typedefs);
2349 util_htdel(vec_last(parser->typedefs));
2350 vec_pop(parser->typedefs);
2352 vec_pop(parser->_block_ctx);
2357 static void parser_addlocal(parser_t *parser, const char *name, ast_expression *e)
2359 vec_push(parser->_locals, e);
2360 util_htset(vec_last(parser->variables), name, (void*)e);
2364 vec_last(parser->correct_variables),
2365 &vec_last(parser->correct_variables_score),
2370 static void parser_addglobal(parser_t *parser, const char *name, ast_expression *e)
2372 vec_push(parser->globals, e);
2373 util_htset(parser->htglobals, name, e);
2377 parser->correct_variables[0],
2378 &parser->correct_variables_score[0],
2383 static ast_expression* process_condition(parser_t *parser, ast_expression *cond, bool *_ifnot)
2387 ast_expression *prev;
2389 if (cond->vtype == TYPE_VOID || cond->vtype >= TYPE_VARIANT) {
2391 ast_type_to_string(cond, ty, sizeof(ty));
2392 compile_error(ast_ctx(cond), "invalid type for if() condition: %s", ty);
2395 if (OPTS_FLAG(FALSE_EMPTY_STRINGS) && cond->vtype == TYPE_STRING)
2398 cond = (ast_expression*)ast_unary_new(ast_ctx(cond), INSTR_NOT_S, cond);
2401 parseerror(parser, "internal error: failed to process condition");
2406 else if (OPTS_FLAG(CORRECT_LOGIC) && cond->vtype == TYPE_VECTOR)
2408 /* vector types need to be cast to true booleans */
2409 ast_binary *bin = (ast_binary*)cond;
2410 if (!OPTS_FLAG(PERL_LOGIC) || !ast_istype(cond, ast_binary) || !(bin->op == INSTR_AND || bin->op == INSTR_OR))
2412 /* in perl-logic, AND and OR take care of the -fcorrect-logic */
2414 cond = (ast_expression*)ast_unary_new(ast_ctx(cond), INSTR_NOT_V, cond);
2417 parseerror(parser, "internal error: failed to process condition");
2424 unary = (ast_unary*)cond;
2425 while (ast_istype(cond, ast_unary) && unary->op == INSTR_NOT_F)
2427 cond = unary->operand;
2428 unary->operand = NULL;
2431 unary = (ast_unary*)cond;
2435 parseerror(parser, "internal error: failed to process condition");
2437 if (ifnot) *_ifnot = !*_ifnot;
2441 static bool parse_if(parser_t *parser, ast_block *block, ast_expression **out)
2444 ast_expression *cond, *ontrue = NULL, *onfalse = NULL;
2447 lex_ctx ctx = parser_ctx(parser);
2449 (void)block; /* not touching */
2451 /* skip the 'if', parse an optional 'not' and check for an opening paren */
2452 if (!parser_next(parser)) {
2453 parseerror(parser, "expected condition or 'not'");
2456 if (parser->tok == TOKEN_IDENT && !strcmp(parser_tokval(parser), "not")) {
2458 if (!parser_next(parser)) {
2459 parseerror(parser, "expected condition in parenthesis");
2463 if (parser->tok != '(') {
2464 parseerror(parser, "expected 'if' condition in parenthesis");
2467 /* parse into the expression */
2468 if (!parser_next(parser)) {
2469 parseerror(parser, "expected 'if' condition after opening paren");
2472 /* parse the condition */
2473 cond = parse_expression_leave(parser, false, true, false);
2477 if (parser->tok != ')') {
2478 parseerror(parser, "expected closing paren after 'if' condition");
2482 /* parse into the 'then' branch */
2483 if (!parser_next(parser)) {
2484 parseerror(parser, "expected statement for on-true branch of 'if'");
2488 if (!parse_statement_or_block(parser, &ontrue)) {
2493 ontrue = (ast_expression*)ast_block_new(parser_ctx(parser));
2494 /* check for an else */
2495 if (!strcmp(parser_tokval(parser), "else")) {
2496 /* parse into the 'else' branch */
2497 if (!parser_next(parser)) {
2498 parseerror(parser, "expected on-false branch after 'else'");
2503 if (!parse_statement_or_block(parser, &onfalse)) {
2510 cond = process_condition(parser, cond, &ifnot);
2512 if (ontrue) ast_delete(ontrue);
2513 if (onfalse) ast_delete(onfalse);
2518 ifthen = ast_ifthen_new(ctx, cond, onfalse, ontrue);
2520 ifthen = ast_ifthen_new(ctx, cond, ontrue, onfalse);
2521 *out = (ast_expression*)ifthen;
2525 static bool parse_while_go(parser_t *parser, ast_block *block, ast_expression **out);
2526 static bool parse_while(parser_t *parser, ast_block *block, ast_expression **out)
2531 /* skip the 'while' and get the body */
2532 if (!parser_next(parser)) {
2533 if (OPTS_FLAG(LOOP_LABELS))
2534 parseerror(parser, "expected loop label or 'while' condition in parenthesis");
2536 parseerror(parser, "expected 'while' condition in parenthesis");
2540 if (parser->tok == ':') {
2541 if (!OPTS_FLAG(LOOP_LABELS))
2542 parseerror(parser, "labeled loops not activated, try using -floop-labels");
2543 if (!parser_next(parser) || parser->tok != TOKEN_IDENT) {
2544 parseerror(parser, "expected loop label");
2547 label = util_strdup(parser_tokval(parser));
2548 if (!parser_next(parser)) {
2550 parseerror(parser, "expected 'while' condition in parenthesis");
2555 if (parser->tok != '(') {
2556 parseerror(parser, "expected 'while' condition in parenthesis");
2560 vec_push(parser->breaks, label);
2561 vec_push(parser->continues, label);
2563 rv = parse_while_go(parser, block, out);
2566 if (vec_last(parser->breaks) != label || vec_last(parser->continues) != label) {
2567 parseerror(parser, "internal error: label stack corrupted");
2573 vec_pop(parser->breaks);
2574 vec_pop(parser->continues);
2579 static bool parse_while_go(parser_t *parser, ast_block *block, ast_expression **out)
2582 ast_expression *cond, *ontrue;
2586 lex_ctx ctx = parser_ctx(parser);
2588 (void)block; /* not touching */
2590 /* parse into the expression */
2591 if (!parser_next(parser)) {
2592 parseerror(parser, "expected 'while' condition after opening paren");
2595 /* parse the condition */
2596 cond = parse_expression_leave(parser, false, true, false);
2600 if (parser->tok != ')') {
2601 parseerror(parser, "expected closing paren after 'while' condition");
2605 /* parse into the 'then' branch */
2606 if (!parser_next(parser)) {
2607 parseerror(parser, "expected while-loop body");
2611 if (!parse_statement_or_block(parser, &ontrue)) {
2616 cond = process_condition(parser, cond, &ifnot);
2621 aloop = ast_loop_new(ctx, NULL, cond, ifnot, NULL, false, NULL, ontrue);
2622 *out = (ast_expression*)aloop;
2626 static bool parse_dowhile_go(parser_t *parser, ast_block *block, ast_expression **out);
2627 static bool parse_dowhile(parser_t *parser, ast_block *block, ast_expression **out)
2632 /* skip the 'do' and get the body */
2633 if (!parser_next(parser)) {
2634 if (OPTS_FLAG(LOOP_LABELS))
2635 parseerror(parser, "expected loop label or body");
2637 parseerror(parser, "expected loop body");
2641 if (parser->tok == ':') {
2642 if (!OPTS_FLAG(LOOP_LABELS))
2643 parseerror(parser, "labeled loops not activated, try using -floop-labels");
2644 if (!parser_next(parser) || parser->tok != TOKEN_IDENT) {
2645 parseerror(parser, "expected loop label");
2648 label = util_strdup(parser_tokval(parser));
2649 if (!parser_next(parser)) {
2651 parseerror(parser, "expected loop body");
2656 vec_push(parser->breaks, label);
2657 vec_push(parser->continues, label);
2659 rv = parse_dowhile_go(parser, block, out);
2662 if (vec_last(parser->breaks) != label || vec_last(parser->continues) != label) {
2663 parseerror(parser, "internal error: label stack corrupted");
2669 vec_pop(parser->breaks);
2670 vec_pop(parser->continues);
2675 static bool parse_dowhile_go(parser_t *parser, ast_block *block, ast_expression **out)
2678 ast_expression *cond, *ontrue;
2682 lex_ctx ctx = parser_ctx(parser);
2684 (void)block; /* not touching */
2686 if (!parse_statement_or_block(parser, &ontrue))
2689 /* expect the "while" */
2690 if (parser->tok != TOKEN_KEYWORD ||
2691 strcmp(parser_tokval(parser), "while"))
2693 parseerror(parser, "expected 'while' and condition");
2698 /* skip the 'while' and check for opening paren */
2699 if (!parser_next(parser) || parser->tok != '(') {
2700 parseerror(parser, "expected 'while' condition in parenthesis");
2704 /* parse into the expression */
2705 if (!parser_next(parser)) {
2706 parseerror(parser, "expected 'while' condition after opening paren");
2710 /* parse the condition */
2711 cond = parse_expression_leave(parser, false, true, false);
2715 if (parser->tok != ')') {
2716 parseerror(parser, "expected closing paren after 'while' condition");
2722 if (!parser_next(parser) || parser->tok != ';') {
2723 parseerror(parser, "expected semicolon after condition");
2729 if (!parser_next(parser)) {
2730 parseerror(parser, "parse error");
2736 cond = process_condition(parser, cond, &ifnot);
2741 aloop = ast_loop_new(ctx, NULL, NULL, false, cond, ifnot, NULL, ontrue);
2742 *out = (ast_expression*)aloop;
2746 static bool parse_for_go(parser_t *parser, ast_block *block, ast_expression **out);
2747 static bool parse_for(parser_t *parser, ast_block *block, ast_expression **out)
2752 /* skip the 'for' and check for opening paren */
2753 if (!parser_next(parser)) {
2754 if (OPTS_FLAG(LOOP_LABELS))
2755 parseerror(parser, "expected loop label or 'for' expressions in parenthesis");
2757 parseerror(parser, "expected 'for' expressions in parenthesis");
2761 if (parser->tok == ':') {
2762 if (!OPTS_FLAG(LOOP_LABELS))
2763 parseerror(parser, "labeled loops not activated, try using -floop-labels");
2764 if (!parser_next(parser) || parser->tok != TOKEN_IDENT) {
2765 parseerror(parser, "expected loop label");
2768 label = util_strdup(parser_tokval(parser));
2769 if (!parser_next(parser)) {
2771 parseerror(parser, "expected 'for' expressions in parenthesis");
2776 if (parser->tok != '(') {
2777 parseerror(parser, "expected 'for' expressions in parenthesis");
2781 vec_push(parser->breaks, label);
2782 vec_push(parser->continues, label);
2784 rv = parse_for_go(parser, block, out);
2787 if (vec_last(parser->breaks) != label || vec_last(parser->continues) != label) {
2788 parseerror(parser, "internal error: label stack corrupted");
2794 vec_pop(parser->breaks);
2795 vec_pop(parser->continues);
2799 static bool parse_for_go(parser_t *parser, ast_block *block, ast_expression **out)
2802 ast_expression *initexpr, *cond, *increment, *ontrue;
2807 lex_ctx ctx = parser_ctx(parser);
2809 parser_enterblock(parser);
2816 /* parse into the expression */
2817 if (!parser_next(parser)) {
2818 parseerror(parser, "expected 'for' initializer after opening paren");
2823 if (parser->tok == TOKEN_IDENT)
2824 typevar = parser_find_typedef(parser, parser_tokval(parser), 0);
2826 if (typevar || parser->tok == TOKEN_TYPENAME) {
2828 if (OPTS_OPTION_U32(OPTION_STANDARD) != COMPILER_GMQCC) {
2829 if (parsewarning(parser, WARN_EXTENSIONS,
2830 "current standard does not allow variable declarations in for-loop initializers"))
2834 if (!parse_variable(parser, block, true, CV_VAR, typevar, false, false, 0, NULL))
2837 else if (parser->tok != ';')
2839 initexpr = parse_expression_leave(parser, false, false, false);
2844 /* move on to condition */
2845 if (parser->tok != ';') {
2846 parseerror(parser, "expected semicolon after for-loop initializer");
2849 if (!parser_next(parser)) {
2850 parseerror(parser, "expected for-loop condition");
2854 /* parse the condition */
2855 if (parser->tok != ';') {
2856 cond = parse_expression_leave(parser, false, true, false);
2861 /* move on to incrementor */
2862 if (parser->tok != ';') {
2863 parseerror(parser, "expected semicolon after for-loop initializer");
2866 if (!parser_next(parser)) {
2867 parseerror(parser, "expected for-loop condition");
2871 /* parse the incrementor */
2872 if (parser->tok != ')') {
2873 lex_ctx condctx = parser_ctx(parser);
2874 increment = parse_expression_leave(parser, false, false, false);
2877 if (!ast_side_effects(increment)) {
2878 if (compile_warning(condctx, WARN_EFFECTLESS_STATEMENT, "statement has no effect"))
2884 if (parser->tok != ')') {
2885 parseerror(parser, "expected closing paren after 'for-loop' incrementor");
2888 /* parse into the 'then' branch */
2889 if (!parser_next(parser)) {
2890 parseerror(parser, "expected for-loop body");
2893 if (!parse_statement_or_block(parser, &ontrue))
2897 cond = process_condition(parser, cond, &ifnot);
2901 aloop = ast_loop_new(ctx, initexpr, cond, ifnot, NULL, false, increment, ontrue);
2902 *out = (ast_expression*)aloop;
2904 if (!parser_leaveblock(parser)) {
2910 if (initexpr) ast_unref(initexpr);
2911 if (cond) ast_unref(cond);
2912 if (increment) ast_unref(increment);
2913 (void)!parser_leaveblock(parser);
2917 static bool parse_return(parser_t *parser, ast_block *block, ast_expression **out)
2919 ast_expression *exp = NULL;
2920 ast_expression *var = NULL;
2921 ast_return *ret = NULL;
2922 ast_value *retval = parser->function->return_value;
2923 ast_value *expected = parser->function->vtype;
2925 lex_ctx ctx = parser_ctx(parser);
2927 (void)block; /* not touching */
2929 if (!parser_next(parser)) {
2930 parseerror(parser, "expected return expression");
2934 /* return assignments */
2935 if (parser->tok == '=') {
2936 if (!OPTS_FLAG(RETURN_ASSIGNMENTS)) {
2937 parseerror(parser, "return assignments not activated, try using -freturn-assigments");
2941 if (type_store_instr[expected->expression.next->vtype] == VINSTR_END) {
2943 ast_type_to_string(expected->expression.next, ty1, sizeof(ty1));
2944 parseerror(parser, "invalid return type: `%s'", ty1);
2948 if (!parser_next(parser)) {
2949 parseerror(parser, "expected return assignment expression");
2953 if (!(exp = parse_expression_leave(parser, false, false, false)))
2956 /* prepare the return value */
2958 retval = ast_value_new(ctx, "#LOCAL_RETURN", TYPE_VOID);
2959 ast_type_adopt(retval, expected->expression.next);
2960 parser->function->return_value = retval;
2963 if (!ast_compare_type(exp, (ast_expression*)retval)) {
2964 char ty1[1024], ty2[1024];
2965 ast_type_to_string(exp, ty1, sizeof(ty1));
2966 ast_type_to_string(&retval->expression, ty2, sizeof(ty2));
2967 parseerror(parser, "invalid type for return value: `%s', expected `%s'", ty1, ty2);
2970 /* store to 'return' local variable */
2971 var = (ast_expression*)ast_store_new(
2973 type_store_instr[expected->expression.next->vtype],
2974 (ast_expression*)retval, exp);
2981 if (parser->tok != ';') {
2982 parser->diagnostic = DIAGNOSTIC_SEMICOLON;
2983 parseerror(parser, "missing semicolon after return assignment");
2984 } else if (!parser_next(parser)) {
2985 parseerror(parser, "parse error after return assignment");
2992 if (parser->tok != ';') {
2993 exp = parse_expression(parser, false, false);
2997 if (exp->vtype != TYPE_NIL &&
2998 exp->vtype != ((ast_expression*)expected)->next->vtype)
3000 parseerror(parser, "return with invalid expression");
3003 ret = ast_return_new(ctx, exp);
3009 if (!parser_next(parser))
3010 parseerror(parser, "parse error");
3012 if (!retval && expected->expression.next->vtype != TYPE_VOID)
3014 (void)!parsewarning(parser, WARN_MISSING_RETURN_VALUES, "return without value");
3016 ret = ast_return_new(ctx, (ast_expression*)retval);
3018 *out = (ast_expression*)ret;
3022 static bool parse_break_continue(parser_t *parser, ast_block *block, ast_expression **out, bool is_continue)
3025 unsigned int levels = 0;
3026 lex_ctx ctx = parser_ctx(parser);
3027 const char **loops = (is_continue ? parser->continues : parser->breaks);
3029 (void)block; /* not touching */
3030 if (!parser_next(parser)) {
3031 parseerror(parser, "expected semicolon or loop label");
3035 if (!vec_size(loops)) {
3037 parseerror(parser, "`continue` can only be used inside loops");
3039 parseerror(parser, "`break` can only be used inside loops or switches");
3042 if (parser->tok == TOKEN_IDENT) {
3043 if (!OPTS_FLAG(LOOP_LABELS))
3044 parseerror(parser, "labeled loops not activated, try using -floop-labels");
3045 i = vec_size(loops);
3047 if (loops[i] && !strcmp(loops[i], parser_tokval(parser)))
3050 parseerror(parser, "no such loop to %s: `%s`",
3051 (is_continue ? "continue" : "break out of"),
3052 parser_tokval(parser));
3057 if (!parser_next(parser)) {
3058 parseerror(parser, "expected semicolon");
3063 if (parser->tok != ';') {
3064 parseerror(parser, "expected semicolon");
3068 if (!parser_next(parser))
3069 parseerror(parser, "parse error");
3071 *out = (ast_expression*)ast_breakcont_new(ctx, is_continue, levels);
3075 /* returns true when it was a variable qualifier, false otherwise!
3076 * on error, cvq is set to CV_WRONG
3078 static bool parse_qualifiers(parser_t *parser, bool with_local, int *cvq, bool *noref, bool *is_static, uint32_t *_flags, char **message)
3080 bool had_const = false;
3081 bool had_var = false;
3082 bool had_noref = false;
3083 bool had_attrib = false;
3084 bool had_static = false;
3089 if (parser->tok == TOKEN_ATTRIBUTE_OPEN) {
3091 /* parse an attribute */
3092 if (!parser_next(parser)) {
3093 parseerror(parser, "expected attribute after `[[`");
3097 if (!strcmp(parser_tokval(parser), "noreturn")) {
3098 flags |= AST_FLAG_NORETURN;
3099 if (!parser_next(parser) || parser->tok != TOKEN_ATTRIBUTE_CLOSE) {
3100 parseerror(parser, "`noreturn` attribute has no parameters, expected `]]`");
3105 else if (!strcmp(parser_tokval(parser), "noref")) {
3107 if (!parser_next(parser) || parser->tok != TOKEN_ATTRIBUTE_CLOSE) {
3108 parseerror(parser, "`noref` attribute has no parameters, expected `]]`");
3113 else if (!strcmp(parser_tokval(parser), "inline")) {
3114 flags |= AST_FLAG_INLINE;
3115 if (!parser_next(parser) || parser->tok != TOKEN_ATTRIBUTE_CLOSE) {
3116 parseerror(parser, "`noref` attribute has no parameters, expected `]]`");
3121 else if (!strcmp(parser_tokval(parser), "alias") && !(flags & AST_FLAG_ALIAS)) {
3122 flags |= AST_FLAG_ALIAS;
3125 if (!parser_next(parser)) {
3126 parseerror(parser, "parse error in attribute");
3130 if (parser->tok == '(') {
3131 if (!parser_next(parser) || parser->tok != TOKEN_STRINGCONST) {
3132 parseerror(parser, "`alias` attribute missing parameter");
3136 *message = util_strdup(parser_tokval(parser));
3138 if (!parser_next(parser)) {
3139 parseerror(parser, "parse error in attribute");
3143 if (parser->tok != ')') {
3144 parseerror(parser, "`alias` attribute expected `)` after parameter");
3148 if (!parser_next(parser)) {
3149 parseerror(parser, "parse error in attribute");
3154 if (parser->tok != TOKEN_ATTRIBUTE_CLOSE) {
3155 parseerror(parser, "`alias` attribute expected `]]`");
3159 else if (!strcmp(parser_tokval(parser), "deprecated") && !(flags & AST_FLAG_DEPRECATED)) {
3160 flags |= AST_FLAG_DEPRECATED;
3163 if (!parser_next(parser)) {
3164 parseerror(parser, "parse error in attribute");
3168 if (parser->tok == '(') {
3169 if (!parser_next(parser) || parser->tok != TOKEN_STRINGCONST) {
3170 parseerror(parser, "`deprecated` attribute missing parameter");
3174 *message = util_strdup(parser_tokval(parser));
3176 if (!parser_next(parser)) {
3177 parseerror(parser, "parse error in attribute");
3181 if(parser->tok != ')') {
3182 parseerror(parser, "`deprecated` attribute expected `)` after parameter");
3186 if (!parser_next(parser)) {
3187 parseerror(parser, "parse error in attribute");
3192 if (parser->tok != TOKEN_ATTRIBUTE_CLOSE) {
3193 parseerror(parser, "`deprecated` attribute expected `]]`");
3196 if (*message) mem_d(*message);
3204 /* Skip tokens until we hit a ]] */
3205 (void)!parsewarning(parser, WARN_UNKNOWN_ATTRIBUTE, "unknown attribute starting with `%s`", parser_tokval(parser));
3206 while (parser->tok != TOKEN_ATTRIBUTE_CLOSE) {
3207 if (!parser_next(parser)) {
3208 parseerror(parser, "error inside attribute");
3215 else if (with_local && !strcmp(parser_tokval(parser), "static"))
3217 else if (!strcmp(parser_tokval(parser), "const"))
3219 else if (!strcmp(parser_tokval(parser), "var"))
3221 else if (with_local && !strcmp(parser_tokval(parser), "local"))
3223 else if (!strcmp(parser_tokval(parser), "noref"))
3225 else if (!had_const && !had_var && !had_noref && !had_attrib && !had_static && !flags) {
3230 if (!parser_next(parser))
3240 *is_static = had_static;
3244 parseerror(parser, "parse error after variable qualifier");
3249 static bool parse_switch_go(parser_t *parser, ast_block *block, ast_expression **out);
3250 static bool parse_switch(parser_t *parser, ast_block *block, ast_expression **out)
3255 /* skip the 'while' and get the body */
3256 if (!parser_next(parser)) {
3257 if (OPTS_FLAG(LOOP_LABELS))
3258 parseerror(parser, "expected loop label or 'switch' operand in parenthesis");
3260 parseerror(parser, "expected 'switch' operand in parenthesis");
3264 if (parser->tok == ':') {
3265 if (!OPTS_FLAG(LOOP_LABELS))
3266 parseerror(parser, "labeled loops not activated, try using -floop-labels");
3267 if (!parser_next(parser) || parser->tok != TOKEN_IDENT) {
3268 parseerror(parser, "expected loop label");
3271 label = util_strdup(parser_tokval(parser));
3272 if (!parser_next(parser)) {
3274 parseerror(parser, "expected 'switch' operand in parenthesis");
3279 if (parser->tok != '(') {
3280 parseerror(parser, "expected 'switch' operand in parenthesis");
3284 vec_push(parser->breaks, label);
3286 rv = parse_switch_go(parser, block, out);
3289 if (vec_last(parser->breaks) != label) {
3290 parseerror(parser, "internal error: label stack corrupted");
3296 vec_pop(parser->breaks);
3301 static bool parse_switch_go(parser_t *parser, ast_block *block, ast_expression **out)
3303 ast_expression *operand;
3306 ast_switch *switchnode;
3307 ast_switch_case swcase;
3310 bool noref, is_static;
3311 uint32_t qflags = 0;
3313 lex_ctx ctx = parser_ctx(parser);
3315 (void)block; /* not touching */
3318 /* parse into the expression */
3319 if (!parser_next(parser)) {
3320 parseerror(parser, "expected switch operand");
3323 /* parse the operand */
3324 operand = parse_expression_leave(parser, false, false, false);
3328 switchnode = ast_switch_new(ctx, operand);
3331 if (parser->tok != ')') {
3332 ast_delete(switchnode);
3333 parseerror(parser, "expected closing paren after 'switch' operand");
3337 /* parse over the opening paren */
3338 if (!parser_next(parser) || parser->tok != '{') {
3339 ast_delete(switchnode);
3340 parseerror(parser, "expected list of cases");
3344 if (!parser_next(parser)) {
3345 ast_delete(switchnode);
3346 parseerror(parser, "expected 'case' or 'default'");
3350 /* new block; allow some variables to be declared here */
3351 parser_enterblock(parser);
3354 if (parser->tok == TOKEN_IDENT)
3355 typevar = parser_find_typedef(parser, parser_tokval(parser), 0);
3356 if (typevar || parser->tok == TOKEN_TYPENAME) {
3357 if (!parse_variable(parser, block, false, CV_NONE, typevar, false, false, 0, NULL)) {
3358 ast_delete(switchnode);
3363 if (parse_qualifiers(parser, true, &cvq, &noref, &is_static, &qflags, NULL))
3365 if (cvq == CV_WRONG) {
3366 ast_delete(switchnode);
3369 if (!parse_variable(parser, block, false, cvq, NULL, noref, is_static, qflags, NULL)) {
3370 ast_delete(switchnode);
3379 while (parser->tok != '}') {
3380 ast_block *caseblock;
3382 if (!strcmp(parser_tokval(parser), "case")) {
3383 if (!parser_next(parser)) {
3384 ast_delete(switchnode);
3385 parser->diagnostic = DIAGNOSTIC_EXPRESSION_CASE;
3386 parseerror(parser, "expected expression for case");
3389 swcase.value = parse_expression_leave(parser, false, false, false);
3390 if (!swcase.value) {
3391 ast_delete(switchnode);
3392 parser->diagnostic = DIAGNOSTIC_EXPRESSION_CASE;
3393 parseerror(parser, "expected expression for case");
3396 if (!OPTS_FLAG(RELAXED_SWITCH)) {
3397 if (!ast_istype(swcase.value, ast_value)) { /* || ((ast_value*)swcase.value)->cvq != CV_CONST) { */
3398 parseerror(parser, "case on non-constant values need to be explicitly enabled via -frelaxed-switch");
3404 else if (!strcmp(parser_tokval(parser), "default")) {
3405 swcase.value = NULL;
3406 if (!parser_next(parser)) {
3407 ast_delete(switchnode);
3408 parseerror(parser, "expected colon");
3413 ast_delete(switchnode);
3414 parseerror(parser, "expected 'case' or 'default'");
3418 /* Now the colon and body */
3419 if (parser->tok != ':') {
3420 if (swcase.value) ast_unref(swcase.value);
3421 ast_delete(switchnode);
3422 parseerror(parser, "expected colon");
3426 if (!parser_next(parser)) {
3427 if (swcase.value) ast_unref(swcase.value);
3428 ast_delete(switchnode);
3429 parseerror(parser, "expected statements or case");
3432 caseblock = ast_block_new(parser_ctx(parser));
3434 if (swcase.value) ast_unref(swcase.value);
3435 ast_delete(switchnode);
3438 swcase.code = (ast_expression*)caseblock;
3439 vec_push(switchnode->cases, swcase);
3441 ast_expression *expr;
3442 if (parser->tok == '}')
3444 if (parser->tok == TOKEN_KEYWORD) {
3445 if (!strcmp(parser_tokval(parser), "case") ||
3446 !strcmp(parser_tokval(parser), "default"))
3451 if (!parse_statement(parser, caseblock, &expr, true)) {
3452 ast_delete(switchnode);
3457 if (!ast_block_add_expr(caseblock, expr)) {
3458 ast_delete(switchnode);
3464 parser_leaveblock(parser);
3467 if (parser->tok != '}') {
3468 ast_delete(switchnode);
3469 parseerror(parser, "expected closing paren of case list");
3472 if (!parser_next(parser)) {
3473 ast_delete(switchnode);
3474 parseerror(parser, "parse error after switch");
3477 *out = (ast_expression*)switchnode;
3481 /* parse computed goto sides */
3482 static ast_expression *parse_goto_computed(parser_t *parser, ast_expression **side) {
3483 ast_expression *on_true;
3484 ast_expression *on_false;
3485 ast_expression *cond;
3490 if (ast_istype(*side, ast_ternary)) {
3491 ast_ternary *tern = (ast_ternary*)*side;
3492 on_true = parse_goto_computed(parser, &tern->on_true);
3493 on_false = parse_goto_computed(parser, &tern->on_false);
3495 if (!on_true || !on_false) {
3496 parseerror(parser, "expected label or expression in ternary");
3497 if (on_true) ast_unref(on_true);
3498 if (on_false) ast_unref(on_false);
3506 return (ast_expression*)ast_ifthen_new(parser_ctx(parser), cond, on_true, on_false);
3507 } else if (ast_istype(*side, ast_label)) {
3508 ast_goto *gt = ast_goto_new(parser_ctx(parser), ((ast_label*)*side)->name);
3509 ast_goto_set_label(gt, ((ast_label*)*side));
3511 return (ast_expression*)gt;
3516 static bool parse_goto(parser_t *parser, ast_expression **out)
3518 ast_goto *gt = NULL;
3519 ast_expression *lbl;
3521 if (!parser_next(parser))
3524 if (parser->tok != TOKEN_IDENT) {
3525 ast_expression *expression;
3527 /* could be an expression i.e computed goto :-) */
3528 if (parser->tok != '(') {
3529 parseerror(parser, "expected label name after `goto`");
3533 /* failed to parse expression for goto */
3534 if (!(expression = parse_expression(parser, false, true)) ||
3535 !(*out = parse_goto_computed(parser, &expression))) {
3536 parseerror(parser, "invalid goto expression");
3537 ast_unref(expression);
3544 /* not computed goto */
3545 gt = ast_goto_new(parser_ctx(parser), parser_tokval(parser));
3546 lbl = parser_find_label(parser, gt->name);
3548 if (!ast_istype(lbl, ast_label)) {
3549 parseerror(parser, "internal error: label is not an ast_label");
3553 ast_goto_set_label(gt, (ast_label*)lbl);
3556 vec_push(parser->gotos, gt);
3558 if (!parser_next(parser) || parser->tok != ';') {
3559 parseerror(parser, "semicolon expected after goto label");
3562 if (!parser_next(parser)) {
3563 parseerror(parser, "parse error after goto");
3567 *out = (ast_expression*)gt;
3571 static bool parse_skipwhite(parser_t *parser)
3574 if (!parser_next(parser))
3576 } while (parser->tok == TOKEN_WHITE && parser->tok < TOKEN_ERROR);
3577 return parser->tok < TOKEN_ERROR;
3580 static bool parse_eol(parser_t *parser)
3582 if (!parse_skipwhite(parser))
3584 return parser->tok == TOKEN_EOL;
3587 static bool parse_pragma_do(parser_t *parser)
3589 if (!parser_next(parser) ||
3590 parser->tok != TOKEN_IDENT ||
3591 strcmp(parser_tokval(parser), "pragma"))
3593 parseerror(parser, "expected `pragma` keyword after `#`, got `%s`", parser_tokval(parser));
3596 if (!parse_skipwhite(parser) || parser->tok != TOKEN_IDENT) {
3597 parseerror(parser, "expected pragma, got `%s`", parser_tokval(parser));
3601 if (!strcmp(parser_tokval(parser), "noref")) {
3602 if (!parse_skipwhite(parser) || parser->tok != TOKEN_INTCONST) {
3603 parseerror(parser, "`noref` pragma requires an argument: 0 or 1");
3606 parser->noref = !!parser_token(parser)->constval.i;
3607 if (!parse_eol(parser)) {
3608 parseerror(parser, "parse error after `noref` pragma");
3614 (void)!parsewarning(parser, WARN_UNKNOWN_PRAGMAS, "ignoring #pragma %s", parser_tokval(parser));
3621 static bool parse_pragma(parser_t *parser)
3624 parser->lex->flags.preprocessing = true;
3625 parser->lex->flags.mergelines = true;
3626 rv = parse_pragma_do(parser);
3627 if (parser->tok != TOKEN_EOL) {
3628 parseerror(parser, "junk after pragma");
3631 parser->lex->flags.preprocessing = false;
3632 parser->lex->flags.mergelines = false;
3633 if (!parser_next(parser)) {
3634 parseerror(parser, "parse error after pragma");
3640 static bool parse_statement(parser_t *parser, ast_block *block, ast_expression **out, bool allow_cases)
3642 bool noref, is_static;
3644 uint32_t qflags = 0;
3645 ast_value *typevar = NULL;
3646 char *vstring = NULL;
3650 if (parser->tok == TOKEN_IDENT)
3651 typevar = parser_find_typedef(parser, parser_tokval(parser), 0);
3653 if (typevar || parser->tok == TOKEN_TYPENAME || parser->tok == '.')
3655 /* local variable */
3657 parseerror(parser, "cannot declare a variable from here");
3660 if (OPTS_OPTION_U32(OPTION_STANDARD) == COMPILER_QCC) {
3661 if (parsewarning(parser, WARN_EXTENSIONS, "missing 'local' keyword when declaring a local variable"))
3664 if (!parse_variable(parser, block, false, CV_NONE, typevar, false, false, 0, NULL))
3668 else if (parse_qualifiers(parser, !!block, &cvq, &noref, &is_static, &qflags, &vstring))
3670 if (cvq == CV_WRONG)
3672 return parse_variable(parser, block, true, cvq, NULL, noref, is_static, qflags, vstring);
3674 else if (parser->tok == TOKEN_KEYWORD)
3676 if (!strcmp(parser_tokval(parser), "__builtin_debug_printtype"))
3681 if (!parser_next(parser)) {
3682 parseerror(parser, "parse error after __builtin_debug_printtype");
3686 if (parser->tok == TOKEN_IDENT && (tdef = parser_find_typedef(parser, parser_tokval(parser), 0)))
3688 ast_type_to_string((ast_expression*)tdef, ty, sizeof(ty));
3689 con_out("__builtin_debug_printtype: `%s`=`%s`\n", tdef->name, ty);
3690 if (!parser_next(parser)) {
3691 parseerror(parser, "parse error after __builtin_debug_printtype typename argument");
3697 if (!parse_statement(parser, block, out, allow_cases))
3700 con_out("__builtin_debug_printtype: got no output node\n");
3703 ast_type_to_string(*out, ty, sizeof(ty));
3704 con_out("__builtin_debug_printtype: `%s`\n", ty);
3709 else if (!strcmp(parser_tokval(parser), "return"))
3711 return parse_return(parser, block, out);
3713 else if (!strcmp(parser_tokval(parser), "if"))
3715 return parse_if(parser, block, out);
3717 else if (!strcmp(parser_tokval(parser), "while"))
3719 return parse_while(parser, block, out);
3721 else if (!strcmp(parser_tokval(parser), "do"))
3723 return parse_dowhile(parser, block, out);
3725 else if (!strcmp(parser_tokval(parser), "for"))
3727 if (OPTS_OPTION_U32(OPTION_STANDARD) == COMPILER_QCC) {
3728 if (parsewarning(parser, WARN_EXTENSIONS, "for loops are not recognized in the original Quake C standard, to enable try an alternate standard --std=?"))
3731 return parse_for(parser, block, out);
3733 else if (!strcmp(parser_tokval(parser), "break"))
3735 return parse_break_continue(parser, block, out, false);
3737 else if (!strcmp(parser_tokval(parser), "continue"))
3739 return parse_break_continue(parser, block, out, true);
3741 else if (!strcmp(parser_tokval(parser), "switch"))
3743 return parse_switch(parser, block, out);
3745 else if (!strcmp(parser_tokval(parser), "case") ||
3746 !strcmp(parser_tokval(parser), "default"))
3749 parseerror(parser, "unexpected 'case' label");
3754 else if (!strcmp(parser_tokval(parser), "goto"))
3756 return parse_goto(parser, out);
3758 else if (!strcmp(parser_tokval(parser), "typedef"))
3760 if (!parser_next(parser)) {
3761 parseerror(parser, "expected type definition after 'typedef'");
3764 return parse_typedef(parser);
3766 parseerror(parser, "Unexpected keyword: `%s'", parser_tokval(parser));
3769 else if (parser->tok == '{')
3772 inner = parse_block(parser);
3775 *out = (ast_expression*)inner;
3778 else if (parser->tok == ':')
3782 if (!parser_next(parser)) {
3783 parseerror(parser, "expected label name");
3786 if (parser->tok != TOKEN_IDENT) {
3787 parseerror(parser, "label must be an identifier");
3790 label = (ast_label*)parser_find_label(parser, parser_tokval(parser));
3792 if (!label->undefined) {
3793 parseerror(parser, "label `%s` already defined", label->name);
3796 label->undefined = false;
3799 label = ast_label_new(parser_ctx(parser), parser_tokval(parser), false);
3800 vec_push(parser->labels, label);
3802 *out = (ast_expression*)label;
3803 if (!parser_next(parser)) {
3804 parseerror(parser, "parse error after label");
3807 for (i = 0; i < vec_size(parser->gotos); ++i) {
3808 if (!strcmp(parser->gotos[i]->name, label->name)) {
3809 ast_goto_set_label(parser->gotos[i], label);
3810 vec_remove(parser->gotos, i, 1);
3816 else if (parser->tok == ';')
3818 if (!parser_next(parser)) {
3819 parseerror(parser, "parse error after empty statement");
3826 lex_ctx ctx = parser_ctx(parser);
3827 ast_expression *exp = parse_expression(parser, false, false);
3831 if (!ast_side_effects(exp)) {
3832 if (compile_warning(ctx, WARN_EFFECTLESS_STATEMENT, "statement has no effect"))
3839 static bool parse_enum(parser_t *parser)
3842 bool reverse = false;
3844 ast_value **values = NULL;
3845 ast_value *var = NULL;
3848 ast_expression *old;
3850 if (!parser_next(parser) || (parser->tok != '{' && parser->tok != ':')) {
3851 parseerror(parser, "expected `{` or `:` after `enum` keyword");
3855 /* enumeration attributes (can add more later) */
3856 if (parser->tok == ':') {
3857 if (!parser_next(parser) || parser->tok != TOKEN_IDENT){
3858 parseerror(parser, "expected `flag` or `reverse` for enumeration attribute");
3863 if (!strcmp(parser_tokval(parser), "flag")) {
3867 else if (!strcmp(parser_tokval(parser), "reverse")) {
3871 parseerror(parser, "invalid attribute `%s` for enumeration", parser_tokval(parser));
3875 if (!parser_next(parser) || parser->tok != '{') {
3876 parseerror(parser, "expected `{` after enum attribute ");
3882 if (!parser_next(parser) || parser->tok != TOKEN_IDENT) {
3883 if (parser->tok == '}') {
3884 /* allow an empty enum */
3887 parseerror(parser, "expected identifier or `}`");
3891 old = parser_find_field(parser, parser_tokval(parser));
3893 old = parser_find_global(parser, parser_tokval(parser));
3895 parseerror(parser, "value `%s` has already been declared here: %s:%i",
3896 parser_tokval(parser), ast_ctx(old).file, ast_ctx(old).line);
3900 var = ast_value_new(parser_ctx(parser), parser_tokval(parser), TYPE_FLOAT);
3901 vec_push(values, var);
3902 var->cvq = CV_CONST;
3903 var->hasvalue = true;
3905 /* for flagged enumerations increment in POTs of TWO */
3906 var->constval.vfloat = (flag) ? (num *= 2) : (num ++);
3907 parser_addglobal(parser, var->name, (ast_expression*)var);
3909 if (!parser_next(parser)) {
3910 parser->diagnostic = DIAGNOSTIC_EXPECTED;
3911 parseerror(parser, "expected `=`, `}` or comma after identifier");
3915 if (parser->tok == ',')
3917 if (parser->tok == '}')
3919 if (parser->tok != '=') {
3920 parser->diagnostic = DIAGNOSTIC_EXPECTED;
3921 parseerror(parser, "expected `=`, `}` or comma after identifier");
3925 if (!parser_next(parser)) {
3926 parseerror(parser, "expected expression after `=`");
3930 /* We got a value! */
3931 old = parse_expression_leave(parser, true, false, false);
3932 asvalue = (ast_value*)old;
3933 if (!ast_istype(old, ast_value) || asvalue->cvq != CV_CONST || !asvalue->hasvalue) {
3934 compile_error(ast_ctx(var), "constant value or expression expected");
3937 num = (var->constval.vfloat = asvalue->constval.vfloat) + 1;
3939 if (parser->tok == '}')
3941 if (parser->tok != ',') {
3942 parseerror(parser, "expected `}` or comma after expression");
3947 /* patch them all (for reversed attribute) */
3950 for (i = 0; i < vec_size(values); i++)
3951 values[i]->constval.vfloat = vec_size(values) - i - 1;
3954 if (parser->tok != '}') {
3955 parseerror(parser, "internal error: breaking without `}`");
3959 if (!parser_next(parser) || parser->tok != ';') {
3960 parser->diagnostic = DIAGNOSTIC_SEMICOLON;
3961 parseerror(parser, "expected semicolon after enumeration");
3965 if (!parser_next(parser)) {
3966 parseerror(parser, "parse error after enumeration");
3978 static bool parse_block_into(parser_t *parser, ast_block *block)
3982 parser_enterblock(parser);
3984 if (!parser_next(parser)) { /* skip the '{' */
3985 parseerror(parser, "expected function body");
3989 while (parser->tok != TOKEN_EOF && parser->tok < TOKEN_ERROR)
3991 ast_expression *expr = NULL;
3992 if (parser->tok == '}')
3995 if (!parse_statement(parser, block, &expr, false)) {
3996 /* parseerror(parser, "parse error"); */
4002 if (!ast_block_add_expr(block, expr)) {
4009 if (parser->tok != '}') {
4012 (void)parser_next(parser);
4016 if (!parser_leaveblock(parser))
4018 return retval && !!block;
4021 static ast_block* parse_block(parser_t *parser)
4024 block = ast_block_new(parser_ctx(parser));
4027 if (!parse_block_into(parser, block)) {
4028 ast_block_delete(block);
4034 static bool parse_statement_or_block(parser_t *parser, ast_expression **out)
4036 if (parser->tok == '{') {
4037 *out = (ast_expression*)parse_block(parser);
4040 return parse_statement(parser, NULL, out, false);
4043 static bool create_vector_members(ast_value *var, ast_member **me)
4046 size_t len = strlen(var->name);
4048 for (i = 0; i < 3; ++i) {
4049 char *name = (char*)mem_a(len+3);
4050 memcpy(name, var->name, len);
4052 name[len+1] = 'x'+i;
4054 me[i] = ast_member_new(ast_ctx(var), (ast_expression*)var, i, name);
4063 do { ast_member_delete(me[--i]); } while(i);
4067 static bool parse_function_body(parser_t *parser, ast_value *var)
4069 ast_block *block = NULL;
4074 ast_expression *framenum = NULL;
4075 ast_expression *nextthink = NULL;
4076 /* None of the following have to be deleted */
4077 ast_expression *fld_think = NULL, *fld_nextthink = NULL, *fld_frame = NULL;
4078 ast_expression *gbl_time = NULL, *gbl_self = NULL;
4079 bool has_frame_think;
4083 has_frame_think = false;
4084 old = parser->function;
4086 if (var->expression.flags & AST_FLAG_ALIAS) {
4087 parseerror(parser, "function aliases cannot have bodies");
4091 if (vec_size(parser->gotos) || vec_size(parser->labels)) {
4092 parseerror(parser, "gotos/labels leaking");
4096 if (!OPTS_FLAG(VARIADIC_ARGS) && var->expression.flags & AST_FLAG_VARIADIC) {
4097 if (parsewarning(parser, WARN_VARIADIC_FUNCTION,
4098 "variadic function with implementation will not be able to access additional parameters (try -fvariadic-args)"))
4104 if (parser->tok == '[') {
4105 /* got a frame definition: [ framenum, nextthink ]
4106 * this translates to:
4107 * self.frame = framenum;
4108 * self.nextthink = time + 0.1;
4109 * self.think = nextthink;
4113 fld_think = parser_find_field(parser, "think");
4114 fld_nextthink = parser_find_field(parser, "nextthink");
4115 fld_frame = parser_find_field(parser, "frame");
4116 if (!fld_think || !fld_nextthink || !fld_frame) {
4117 parseerror(parser, "cannot use [frame,think] notation without the required fields");
4118 parseerror(parser, "please declare the following entityfields: `frame`, `think`, `nextthink`");
4121 gbl_time = parser_find_global(parser, "time");
4122 gbl_self = parser_find_global(parser, "self");
4123 if (!gbl_time || !gbl_self) {
4124 parseerror(parser, "cannot use [frame,think] notation without the required globals");
4125 parseerror(parser, "please declare the following globals: `time`, `self`");
4129 if (!parser_next(parser))
4132 framenum = parse_expression_leave(parser, true, false, false);
4134 parseerror(parser, "expected a framenumber constant in[frame,think] notation");
4137 if (!ast_istype(framenum, ast_value) || !( (ast_value*)framenum )->hasvalue) {
4138 ast_unref(framenum);
4139 parseerror(parser, "framenumber in [frame,think] notation must be a constant");
4143 if (parser->tok != ',') {
4144 ast_unref(framenum);
4145 parseerror(parser, "expected comma after frame number in [frame,think] notation");
4146 parseerror(parser, "Got a %i\n", parser->tok);
4150 if (!parser_next(parser)) {
4151 ast_unref(framenum);
4155 if (parser->tok == TOKEN_IDENT && !parser_find_var(parser, parser_tokval(parser)))
4157 /* qc allows the use of not-yet-declared functions here
4158 * - this automatically creates a prototype */
4159 ast_value *thinkfunc;
4160 ast_expression *functype = fld_think->next;
4162 thinkfunc = ast_value_new(parser_ctx(parser), parser_tokval(parser), functype->vtype);
4163 if (!thinkfunc) { /* || !ast_type_adopt(thinkfunc, functype)*/
4164 ast_unref(framenum);
4165 parseerror(parser, "failed to create implicit prototype for `%s`", parser_tokval(parser));
4168 ast_type_adopt(thinkfunc, functype);
4170 if (!parser_next(parser)) {
4171 ast_unref(framenum);
4172 ast_delete(thinkfunc);
4176 parser_addglobal(parser, thinkfunc->name, (ast_expression*)thinkfunc);
4178 nextthink = (ast_expression*)thinkfunc;
4181 nextthink = parse_expression_leave(parser, true, false, false);
4183 ast_unref(framenum);
4184 parseerror(parser, "expected a think-function in [frame,think] notation");
4189 if (!ast_istype(nextthink, ast_value)) {
4190 parseerror(parser, "think-function in [frame,think] notation must be a constant");
4194 if (retval && parser->tok != ']') {
4195 parseerror(parser, "expected closing `]` for [frame,think] notation");
4199 if (retval && !parser_next(parser)) {
4203 if (retval && parser->tok != '{') {
4204 parseerror(parser, "a function body has to be declared after a [frame,think] declaration");
4209 ast_unref(nextthink);
4210 ast_unref(framenum);
4214 has_frame_think = true;
4217 block = ast_block_new(parser_ctx(parser));
4219 parseerror(parser, "failed to allocate block");
4220 if (has_frame_think) {
4221 ast_unref(nextthink);
4222 ast_unref(framenum);
4227 if (has_frame_think) {
4229 ast_expression *self_frame;
4230 ast_expression *self_nextthink;
4231 ast_expression *self_think;
4232 ast_expression *time_plus_1;
4233 ast_store *store_frame;
4234 ast_store *store_nextthink;
4235 ast_store *store_think;
4237 ctx = parser_ctx(parser);
4238 self_frame = (ast_expression*)ast_entfield_new(ctx, gbl_self, fld_frame);
4239 self_nextthink = (ast_expression*)ast_entfield_new(ctx, gbl_self, fld_nextthink);
4240 self_think = (ast_expression*)ast_entfield_new(ctx, gbl_self, fld_think);
4242 time_plus_1 = (ast_expression*)ast_binary_new(ctx, INSTR_ADD_F,
4243 gbl_time, (ast_expression*)parser_const_float(parser, 0.1));
4245 if (!self_frame || !self_nextthink || !self_think || !time_plus_1) {
4246 if (self_frame) ast_delete(self_frame);
4247 if (self_nextthink) ast_delete(self_nextthink);
4248 if (self_think) ast_delete(self_think);
4249 if (time_plus_1) ast_delete(time_plus_1);
4255 store_frame = ast_store_new(ctx, INSTR_STOREP_F, self_frame, framenum);
4256 store_nextthink = ast_store_new(ctx, INSTR_STOREP_F, self_nextthink, time_plus_1);
4257 store_think = ast_store_new(ctx, INSTR_STOREP_FNC, self_think, nextthink);
4260 ast_delete(self_frame);
4263 if (!store_nextthink) {
4264 ast_delete(self_nextthink);
4268 ast_delete(self_think);
4272 if (store_frame) ast_delete(store_frame);
4273 if (store_nextthink) ast_delete(store_nextthink);
4274 if (store_think) ast_delete(store_think);
4277 if (!ast_block_add_expr(block, (ast_expression*)store_frame) ||
4278 !ast_block_add_expr(block, (ast_expression*)store_nextthink) ||
4279 !ast_block_add_expr(block, (ast_expression*)store_think))
4286 parseerror(parser, "failed to generate code for [frame,think]");
4287 ast_unref(nextthink);
4288 ast_unref(framenum);
4294 if (var->hasvalue) {
4295 parseerror(parser, "function `%s` declared with multiple bodies", var->name);
4296 ast_block_delete(block);
4300 func = ast_function_new(ast_ctx(var), var->name, var);
4302 parseerror(parser, "failed to allocate function for `%s`", var->name);
4303 ast_block_delete(block);
4306 vec_push(parser->functions, func);
4308 parser_enterblock(parser);
4310 for (parami = 0; parami < vec_size(var->expression.params); ++parami) {
4312 ast_value *param = var->expression.params[parami];
4315 if (param->expression.vtype != TYPE_VECTOR &&
4316 (param->expression.vtype != TYPE_FIELD ||
4317 param->expression.next->vtype != TYPE_VECTOR))
4322 if (!create_vector_members(param, me)) {
4323 ast_block_delete(block);
4327 for (e = 0; e < 3; ++e) {
4328 parser_addlocal(parser, me[e]->name, (ast_expression*)me[e]);
4329 ast_block_collect(block, (ast_expression*)me[e]);
4333 if (var->argcounter) {
4334 ast_value *argc = ast_value_new(ast_ctx(var), var->argcounter, TYPE_FLOAT);
4335 parser_addlocal(parser, argc->name, (ast_expression*)argc);
4339 if (OPTS_FLAG(VARIADIC_ARGS) && var->expression.flags & AST_FLAG_VARIADIC) {
4341 ast_value *varargs = ast_value_new(ast_ctx(var), "reserved:va_args", TYPE_ARRAY);
4342 varargs->expression.flags |= AST_FLAG_IS_VARARG;
4343 varargs->expression.next = (ast_expression*)ast_value_new(ast_ctx(var), NULL, TYPE_VECTOR);
4344 varargs->expression.count = 0;
4345 util_snprintf(name, sizeof(name), "%s##va##SET", var->name);
4346 if (!parser_create_array_setter_proto(parser, varargs, name)) {
4347 ast_delete(varargs);
4348 ast_block_delete(block);
4351 util_snprintf(name, sizeof(name), "%s##va##GET", var->name);
4352 if (!parser_create_array_getter_proto(parser, varargs, varargs->expression.next, name)) {
4353 ast_delete(varargs);
4354 ast_block_delete(block);
4357 func->varargs = varargs;
4359 func->fixedparams = parser_const_float(parser, vec_size(var->expression.params));
4362 parser->function = func;
4363 if (!parse_block_into(parser, block)) {
4364 ast_block_delete(block);
4368 vec_push(func->blocks, block);
4371 parser->function = old;
4372 if (!parser_leaveblock(parser))
4374 if (vec_size(parser->variables) != PARSER_HT_LOCALS) {
4375 parseerror(parser, "internal error: local scopes left");
4379 if (parser->tok == ';')
4380 return parser_next(parser);
4381 else if (OPTS_OPTION_U32(OPTION_STANDARD) == COMPILER_QCC)
4382 parseerror(parser, "missing semicolon after function body (mandatory with -std=qcc)");
4386 (void)!parser_leaveblock(parser);
4387 vec_pop(parser->functions);
4388 ast_function_delete(func);
4389 var->constval.vfunc = NULL;
4392 parser->function = old;
4396 static ast_expression *array_accessor_split(
4401 ast_expression *left,
4402 ast_expression *right
4408 lex_ctx ctx = ast_ctx(array);
4410 if (!left || !right) {
4411 if (left) ast_delete(left);
4412 if (right) ast_delete(right);
4416 cmp = ast_binary_new(ctx, INSTR_LT,
4417 (ast_expression*)index,
4418 (ast_expression*)parser_const_float(parser, middle));
4422 parseerror(parser, "internal error: failed to create comparison for array setter");
4426 ifthen = ast_ifthen_new(ctx, (ast_expression*)cmp, left, right);
4428 ast_delete(cmp); /* will delete left and right */
4429 parseerror(parser, "internal error: failed to create conditional jump for array setter");
4433 return (ast_expression*)ifthen;
4436 static ast_expression *array_setter_node(parser_t *parser, ast_value *array, ast_value *index, ast_value *value, size_t from, size_t afterend)
4438 lex_ctx ctx = ast_ctx(array);
4440 if (from+1 == afterend) {
4441 /* set this value */
4444 ast_array_index *subscript;
4446 int assignop = type_store_instr[value->expression.vtype];
4448 if (value->expression.vtype == TYPE_FIELD && value->expression.next->vtype == TYPE_VECTOR)
4449 assignop = INSTR_STORE_V;
4451 subscript = ast_array_index_new(ctx, (ast_expression*)array, (ast_expression*)parser_const_float(parser, from));
4455 st = ast_store_new(ctx, assignop, (ast_expression*)subscript, (ast_expression*)value);
4457 ast_delete(subscript);
4461 block = ast_block_new(ctx);
4467 if (!ast_block_add_expr(block, (ast_expression*)st)) {
4472 ret = ast_return_new(ctx, NULL);
4478 if (!ast_block_add_expr(block, (ast_expression*)ret)) {
4483 return (ast_expression*)block;
4485 ast_expression *left, *right;
4486 size_t diff = afterend - from;
4487 size_t middle = from + diff/2;
4488 left = array_setter_node(parser, array, index, value, from, middle);
4489 right = array_setter_node(parser, array, index, value, middle, afterend);
4490 return array_accessor_split(parser, array, index, middle, left, right);
4494 static ast_expression *array_field_setter_node(
4503 lex_ctx ctx = ast_ctx(array);
4505 if (from+1 == afterend) {
4506 /* set this value */
4509 ast_entfield *entfield;
4510 ast_array_index *subscript;
4512 int assignop = type_storep_instr[value->expression.vtype];
4514 if (value->expression.vtype == TYPE_FIELD && value->expression.next->vtype == TYPE_VECTOR)
4515 assignop = INSTR_STOREP_V;
4517 subscript = ast_array_index_new(ctx, (ast_expression*)array, (ast_expression*)parser_const_float(parser, from));
4521 subscript->expression.next = ast_type_copy(ast_ctx(subscript), (ast_expression*)subscript);
4522 subscript->expression.vtype = TYPE_FIELD;
4524 entfield = ast_entfield_new_force(ctx,
4525 (ast_expression*)entity,
4526 (ast_expression*)subscript,
4527 (ast_expression*)subscript);
4529 ast_delete(subscript);
4533 st = ast_store_new(ctx, assignop, (ast_expression*)entfield, (ast_expression*)value);
4535 ast_delete(entfield);
4539 block = ast_block_new(ctx);
4545 if (!ast_block_add_expr(block, (ast_expression*)st)) {
4550 ret = ast_return_new(ctx, NULL);
4556 if (!ast_block_add_expr(block, (ast_expression*)ret)) {
4561 return (ast_expression*)block;
4563 ast_expression *left, *right;
4564 size_t diff = afterend - from;
4565 size_t middle = from + diff/2;
4566 left = array_field_setter_node(parser, array, entity, index, value, from, middle);
4567 right = array_field_setter_node(parser, array, entity, index, value, middle, afterend);
4568 return array_accessor_split(parser, array, index, middle, left, right);
4572 static ast_expression *array_getter_node(parser_t *parser, ast_value *array, ast_value *index, size_t from, size_t afterend)
4574 lex_ctx ctx = ast_ctx(array);
4576 if (from+1 == afterend) {
4578 ast_array_index *subscript;
4580 subscript = ast_array_index_new(ctx, (ast_expression*)array, (ast_expression*)parser_const_float(parser, from));
4584 ret = ast_return_new(ctx, (ast_expression*)subscript);
4586 ast_delete(subscript);
4590 return (ast_expression*)ret;
4592 ast_expression *left, *right;
4593 size_t diff = afterend - from;
4594 size_t middle = from + diff/2;
4595 left = array_getter_node(parser, array, index, from, middle);
4596 right = array_getter_node(parser, array, index, middle, afterend);
4597 return array_accessor_split(parser, array, index, middle, left, right);
4601 static bool parser_create_array_accessor(parser_t *parser, ast_value *array, const char *funcname, ast_value **out)
4603 ast_function *func = NULL;
4604 ast_value *fval = NULL;
4605 ast_block *body = NULL;
4607 fval = ast_value_new(ast_ctx(array), funcname, TYPE_FUNCTION);
4609 parseerror(parser, "failed to create accessor function value");
4613 func = ast_function_new(ast_ctx(array), funcname, fval);
4616 parseerror(parser, "failed to create accessor function node");
4620 body = ast_block_new(ast_ctx(array));
4622 parseerror(parser, "failed to create block for array accessor");
4628 vec_push(func->blocks, body);
4631 vec_push(parser->accessors, fval);
4636 static ast_value* parser_create_array_setter_proto(parser_t *parser, ast_value *array, const char *funcname)
4638 ast_value *index = NULL;
4639 ast_value *value = NULL;
4643 if (!ast_istype(array->expression.next, ast_value)) {
4644 parseerror(parser, "internal error: array accessor needs to build an ast_value with a copy of the element type");
4648 if (!parser_create_array_accessor(parser, array, funcname, &fval))
4650 func = fval->constval.vfunc;
4651 fval->expression.next = (ast_expression*)ast_value_new(ast_ctx(array), "<void>", TYPE_VOID);
4653 index = ast_value_new(ast_ctx(array), "index", TYPE_FLOAT);
4654 value = ast_value_copy((ast_value*)array->expression.next);
4656 if (!index || !value) {
4657 parseerror(parser, "failed to create locals for array accessor");
4660 (void)!ast_value_set_name(value, "value"); /* not important */
4661 vec_push(fval->expression.params, index);
4662 vec_push(fval->expression.params, value);
4664 array->setter = fval;
4667 if (index) ast_delete(index);
4668 if (value) ast_delete(value);
4674 static bool parser_create_array_setter_impl(parser_t *parser, ast_value *array)
4676 ast_expression *root = NULL;
4677 root = array_setter_node(parser, array,
4678 array->setter->expression.params[0],
4679 array->setter->expression.params[1],
4680 0, array->expression.count);
4682 parseerror(parser, "failed to build accessor search tree");
4685 if (!ast_block_add_expr(array->setter->constval.vfunc->blocks[0], root)) {
4692 static bool parser_create_array_setter(parser_t *parser, ast_value *array, const char *funcname)
4694 if (!parser_create_array_setter_proto(parser, array, funcname))
4696 return parser_create_array_setter_impl(parser, array);
4699 static bool parser_create_array_field_setter(parser_t *parser, ast_value *array, const char *funcname)
4701 ast_expression *root = NULL;
4702 ast_value *entity = NULL;
4703 ast_value *index = NULL;
4704 ast_value *value = NULL;
4708 if (!ast_istype(array->expression.next, ast_value)) {
4709 parseerror(parser, "internal error: array accessor needs to build an ast_value with a copy of the element type");
4713 if (!parser_create_array_accessor(parser, array, funcname, &fval))
4715 func = fval->constval.vfunc;
4716 fval->expression.next = (ast_expression*)ast_value_new(ast_ctx(array), "<void>", TYPE_VOID);
4718 entity = ast_value_new(ast_ctx(array), "entity", TYPE_ENTITY);
4719 index = ast_value_new(ast_ctx(array), "index", TYPE_FLOAT);
4720 value = ast_value_copy((ast_value*)array->expression.next);
4721 if (!entity || !index || !value) {
4722 parseerror(parser, "failed to create locals for array accessor");
4725 (void)!ast_value_set_name(value, "value"); /* not important */
4726 vec_push(fval->expression.params, entity);
4727 vec_push(fval->expression.params, index);
4728 vec_push(fval->expression.params, value);
4730 root = array_field_setter_node(parser, array, entity, index, value, 0, array->expression.count);
4732 parseerror(parser, "failed to build accessor search tree");
4736 array->setter = fval;
4737 return ast_block_add_expr(func->blocks[0], root);
4739 if (entity) ast_delete(entity);
4740 if (index) ast_delete(index);
4741 if (value) ast_delete(value);
4742 if (root) ast_delete(root);
4748 static ast_value* parser_create_array_getter_proto(parser_t *parser, ast_value *array, const ast_expression *elemtype, const char *funcname)
4750 ast_value *index = NULL;
4754 /* NOTE: checking array->expression.next rather than elemtype since
4755 * for fields elemtype is a temporary fieldtype.
4757 if (!ast_istype(array->expression.next, ast_value)) {
4758 parseerror(parser, "internal error: array accessor needs to build an ast_value with a copy of the element type");
4762 if (!parser_create_array_accessor(parser, array, funcname, &fval))
4764 func = fval->constval.vfunc;
4765 fval->expression.next = ast_type_copy(ast_ctx(array), elemtype);
4767 index = ast_value_new(ast_ctx(array), "index", TYPE_FLOAT);
4770 parseerror(parser, "failed to create locals for array accessor");
4773 vec_push(fval->expression.params, index);
4775 array->getter = fval;
4778 if (index) ast_delete(index);
4784 static bool parser_create_array_getter_impl(parser_t *parser, ast_value *array)
4786 ast_expression *root = NULL;
4788 root = array_getter_node(parser, array, array->getter->expression.params[0], 0, array->expression.count);
4790 parseerror(parser, "failed to build accessor search tree");
4793 if (!ast_block_add_expr(array->getter->constval.vfunc->blocks[0], root)) {
4800 static bool parser_create_array_getter(parser_t *parser, ast_value *array, const ast_expression *elemtype, const char *funcname)
4802 if (!parser_create_array_getter_proto(parser, array, elemtype, funcname))
4804 return parser_create_array_getter_impl(parser, array);
4807 static ast_value *parse_typename(parser_t *parser, ast_value **storebase, ast_value *cached_typedef);
4808 static ast_value *parse_parameter_list(parser_t *parser, ast_value *var)
4816 bool variadic = false;
4817 ast_value *varparam = NULL;
4818 char *argcounter = NULL;
4820 ctx = parser_ctx(parser);
4822 /* for the sake of less code we parse-in in this function */
4823 if (!parser_next(parser)) {
4825 parseerror(parser, "expected parameter list");
4831 /* parse variables until we hit a closing paren */
4832 while (parser->tok != ')') {
4834 /* there must be commas between them */
4835 if (parser->tok != ',') {
4836 parseerror(parser, "expected comma or end of parameter list");
4839 if (!parser_next(parser)) {
4840 parseerror(parser, "expected parameter");
4846 if (parser->tok == TOKEN_DOTS) {
4847 /* '...' indicates a varargs function */
4849 if (!parser_next(parser) || (parser->tok != ')' && parser->tok != TOKEN_IDENT)) {
4850 parseerror(parser, "`...` must be the last parameter of a variadic function declaration");
4853 if (parser->tok == TOKEN_IDENT) {
4854 argcounter = util_strdup(parser_tokval(parser));
4855 if (!parser_next(parser) || parser->tok != ')') {
4856 parseerror(parser, "`...` must be the last parameter of a variadic function declaration");
4863 /* for anything else just parse a typename */
4864 param = parse_typename(parser, NULL, NULL);
4867 vec_push(params, param);
4868 if (param->expression.vtype >= TYPE_VARIANT) {
4869 char tname[1024]; /* typename is reserved in C++ */
4870 ast_type_to_string((ast_expression*)param, tname, sizeof(tname));
4871 parseerror(parser, "type not supported as part of a parameter list: %s", tname);
4874 /* type-restricted varargs */
4875 if (parser->tok == TOKEN_DOTS) {
4877 varparam = vec_last(params);
4879 if (!parser_next(parser) || (parser->tok != ')' && parser->tok != TOKEN_IDENT)) {
4880 parseerror(parser, "`...` must be the last parameter of a variadic function declaration");
4883 if (parser->tok == TOKEN_IDENT) {
4884 argcounter = util_strdup(parser_tokval(parser));
4885 if (!parser_next(parser) || parser->tok != ')') {
4886 parseerror(parser, "`...` must be the last parameter of a variadic function declaration");
4894 if (vec_size(params) == 1 && params[0]->expression.vtype == TYPE_VOID)
4898 if (vec_size(params) > 8 && OPTS_OPTION_U32(OPTION_STANDARD) == COMPILER_QCC)
4899 (void)!parsewarning(parser, WARN_EXTENSIONS, "more than 8 parameters are not supported by this standard");
4902 if (!parser_next(parser)) {
4903 parseerror(parser, "parse error after typename");
4907 /* now turn 'var' into a function type */
4908 fval = ast_value_new(ctx, "<type()>", TYPE_FUNCTION);
4909 fval->expression.next = (ast_expression*)var;
4911 fval->expression.flags |= AST_FLAG_VARIADIC;
4914 var->expression.params = params;
4915 var->expression.varparam = (ast_expression*)varparam;
4916 var->argcounter = argcounter;
4925 ast_delete(varparam);
4927 for (i = 0; i < vec_size(params); ++i)
4928 ast_delete(params[i]);
4933 static ast_value *parse_arraysize(parser_t *parser, ast_value *var)
4935 ast_expression *cexp;
4936 ast_value *cval, *tmp;
4939 ctx = parser_ctx(parser);
4941 if (!parser_next(parser)) {
4943 parseerror(parser, "expected array-size");
4947 cexp = parse_expression_leave(parser, true, false, false);
4949 if (!cexp || !ast_istype(cexp, ast_value)) {
4953 parseerror(parser, "expected array-size as constant positive integer");
4956 cval = (ast_value*)cexp;
4958 tmp = ast_value_new(ctx, "<type[]>", TYPE_ARRAY);
4959 tmp->expression.next = (ast_expression*)var;
4962 if (cval->expression.vtype == TYPE_INTEGER)
4963 tmp->expression.count = cval->constval.vint;
4964 else if (cval->expression.vtype == TYPE_FLOAT)
4965 tmp->expression.count = cval->constval.vfloat;
4969 parseerror(parser, "array-size must be a positive integer constant");
4974 if (parser->tok != ']') {
4976 parseerror(parser, "expected ']' after array-size");
4979 if (!parser_next(parser)) {
4981 parseerror(parser, "error after parsing array size");
4987 /* Parse a complete typename.
4988 * for single-variables (ie. function parameters or typedefs) storebase should be NULL
4989 * but when parsing variables separated by comma
4990 * 'storebase' should point to where the base-type should be kept.
4991 * The base type makes up every bit of type information which comes *before* the
4994 * The following will be parsed in its entirety:
4996 * The 'basetype' in this case is 'void()'
4997 * and if there's a comma after it, say:
4999 * then the type-information 'void()' can be stored in 'storebase'
5001 static ast_value *parse_typename(parser_t *parser, ast_value **storebase, ast_value *cached_typedef)
5003 ast_value *var, *tmp;
5006 const char *name = NULL;
5007 bool isfield = false;
5008 bool wasarray = false;
5009 size_t morefields = 0;
5011 ctx = parser_ctx(parser);
5013 /* types may start with a dot */
5014 if (parser->tok == '.') {
5016 /* if we parsed a dot we need a typename now */
5017 if (!parser_next(parser)) {
5018 parseerror(parser, "expected typename for field definition");
5022 /* Further dots are handled seperately because they won't be part of the
5025 while (parser->tok == '.') {
5027 if (!parser_next(parser)) {
5028 parseerror(parser, "expected typename for field definition");
5033 if (parser->tok == TOKEN_IDENT)
5034 cached_typedef = parser_find_typedef(parser, parser_tokval(parser), 0);
5035 if (!cached_typedef && parser->tok != TOKEN_TYPENAME) {
5036 parseerror(parser, "expected typename");
5040 /* generate the basic type value */
5041 if (cached_typedef) {
5042 var = ast_value_copy(cached_typedef);
5043 ast_value_set_name(var, "<type(from_def)>");
5045 var = ast_value_new(ctx, "<type>", parser_token(parser)->constval.t);
5047 for (; morefields; --morefields) {
5048 tmp = ast_value_new(ctx, "<.type>", TYPE_FIELD);
5049 tmp->expression.next = (ast_expression*)var;
5053 /* do not yet turn into a field - remember:
5054 * .void() foo; is a field too
5055 * .void()() foo; is a function
5059 if (!parser_next(parser)) {
5061 parseerror(parser, "parse error after typename");
5065 /* an opening paren now starts the parameter-list of a function
5066 * this is where original-QC has parameter lists.
5067 * We allow a single parameter list here.
5068 * Much like fteqcc we don't allow `float()() x`
5070 if (parser->tok == '(') {
5071 var = parse_parameter_list(parser, var);
5076 /* store the base if requested */
5078 *storebase = ast_value_copy(var);
5080 tmp = ast_value_new(ctx, "<type:f>", TYPE_FIELD);
5081 tmp->expression.next = (ast_expression*)*storebase;
5086 /* there may be a name now */
5087 if (parser->tok == TOKEN_IDENT) {
5088 name = util_strdup(parser_tokval(parser));
5090 if (!parser_next(parser)) {
5093 parseerror(parser, "error after variable or field declaration");
5098 /* now this may be an array */
5099 if (parser->tok == '[') {
5101 var = parse_arraysize(parser, var);
5103 if (name) mem_d(name);
5108 /* This is the point where we can turn it into a field */
5110 /* turn it into a field if desired */
5111 tmp = ast_value_new(ctx, "<type:f>", TYPE_FIELD);
5112 tmp->expression.next = (ast_expression*)var;
5116 /* now there may be function parens again */
5117 if (parser->tok == '(' && OPTS_OPTION_U32(OPTION_STANDARD) == COMPILER_QCC)
5118 parseerror(parser, "C-style function syntax is not allowed in -std=qcc");
5119 if (parser->tok == '(' && wasarray)
5120 parseerror(parser, "arrays as part of a return type is not supported");
5121 while (parser->tok == '(') {
5122 var = parse_parameter_list(parser, var);
5124 if (name) mem_d(name);
5129 /* finally name it */
5131 if (!ast_value_set_name(var, name)) {
5134 parseerror(parser, "internal error: failed to set name");
5137 /* free the name, ast_value_set_name duplicates */
5144 static bool parse_typedef(parser_t *parser)
5146 ast_value *typevar, *oldtype;
5147 ast_expression *old;
5149 typevar = parse_typename(parser, NULL, NULL);
5154 if ( (old = parser_find_var(parser, typevar->name)) ) {
5155 parseerror(parser, "cannot define a type with the same name as a variable: %s\n"
5156 " -> `%s` has been declared here: %s:%i",
5157 typevar->name, ast_ctx(old).file, ast_ctx(old).line);
5158 ast_delete(typevar);
5162 if ( (oldtype = parser_find_typedef(parser, typevar->name, vec_last(parser->_blocktypedefs))) ) {
5163 parseerror(parser, "type `%s` has already been declared here: %s:%i",
5164 typevar->name, ast_ctx(oldtype).file, ast_ctx(oldtype).line);
5165 ast_delete(typevar);
5169 vec_push(parser->_typedefs, typevar);
5170 util_htset(vec_last(parser->typedefs), typevar->name, typevar);
5172 if (parser->tok != ';') {
5173 parseerror(parser, "expected semicolon after typedef");
5176 if (!parser_next(parser)) {
5177 parseerror(parser, "parse error after typedef");
5184 static const char *cvq_to_str(int cvq) {
5186 case CV_NONE: return "none";
5187 case CV_VAR: return "`var`";
5188 case CV_CONST: return "`const`";
5189 default: return "<INVALID>";
5193 static bool parser_check_qualifiers(parser_t *parser, const ast_value *var, const ast_value *proto)
5196 if (proto->cvq != var->cvq) {
5197 if (!(proto->cvq == CV_CONST && var->cvq == CV_NONE &&
5198 !OPTS_FLAG(INITIALIZED_NONCONSTANTS) &&
5199 parser->tok == '='))
5201 return !parsewarning(parser, WARN_DIFFERENT_QUALIFIERS,
5202 "`%s` declared with different qualifiers: %s\n"
5203 " -> previous declaration here: %s:%i uses %s",
5204 var->name, cvq_to_str(var->cvq),
5205 ast_ctx(proto).file, ast_ctx(proto).line,
5206 cvq_to_str(proto->cvq));
5209 av = (var ->expression.flags & AST_FLAG_NORETURN);
5210 ao = (proto->expression.flags & AST_FLAG_NORETURN);
5212 return !parsewarning(parser, WARN_DIFFERENT_ATTRIBUTES,
5213 "`%s` declared with different attributes%s\n"
5214 " -> previous declaration here: %s:%i",
5215 var->name, (av ? ": noreturn" : ""),
5216 ast_ctx(proto).file, ast_ctx(proto).line,
5217 (ao ? ": noreturn" : ""));
5222 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)
5226 ast_expression *old;
5230 ast_value *basetype = NULL;
5232 bool isparam = false;
5233 bool isvector = false;
5234 bool cleanvar = true;
5235 bool wasarray = false;
5237 ast_member *me[3] = { NULL, NULL, NULL };
5239 if (!localblock && is_static)
5240 parseerror(parser, "`static` qualifier is not supported in global scope");
5242 /* get the first complete variable */
5243 var = parse_typename(parser, &basetype, cached_typedef);
5246 ast_delete(basetype);
5251 ast_expression *cexp;
5257 /* Part 0: finish the type */
5258 if (parser->tok == '(') {
5259 if (OPTS_OPTION_U32(OPTION_STANDARD) == COMPILER_QCC)
5260 parseerror(parser, "C-style function syntax is not allowed in -std=qcc");
5261 var = parse_parameter_list(parser, var);
5267 /* we only allow 1-dimensional arrays */
5268 if (parser->tok == '[') {
5270 var = parse_arraysize(parser, var);
5276 if (parser->tok == '(' && wasarray) {
5277 parseerror(parser, "arrays as part of a return type is not supported");
5278 /* we'll still parse the type completely for now */
5280 /* for functions returning functions */
5281 while (parser->tok == '(') {
5282 if (OPTS_OPTION_U32(OPTION_STANDARD) == COMPILER_QCC)
5283 parseerror(parser, "C-style function syntax is not allowed in -std=qcc");
5284 var = parse_parameter_list(parser, var);
5291 var->cvq = qualifier;
5292 var->expression.flags |= qflags;
5295 * store the vstring back to var for alias and
5296 * deprecation messages.
5298 if (var->expression.flags & AST_FLAG_DEPRECATED ||
5299 var->expression.flags & AST_FLAG_ALIAS)
5300 var->desc = vstring;
5303 * check for validity: (end_sys_..., multiple-definitions, prototypes, ...)
5304 * Also: if there was a prototype, `var` will be deleted and set to `proto` which
5305 * is then filled with the previous definition and the parameter-names replaced.
5307 if (!strcmp(var->name, "nil")) {
5308 if (OPTS_FLAG(UNTYPED_NIL)) {
5309 if (!localblock || !OPTS_FLAG(PERMISSIVE))
5310 parseerror(parser, "name `nil` not allowed (try -fpermissive)");
5312 (void)!parsewarning(parser, WARN_RESERVED_NAMES, "variable name `nil` is reserved");
5315 /* Deal with end_sys_ vars */
5317 if (!strcmp(var->name, "end_sys_globals")) {
5319 parser->crc_globals = vec_size(parser->globals);
5322 else if (!strcmp(var->name, "end_sys_fields")) {
5324 parser->crc_fields = vec_size(parser->fields);
5327 if (was_end && var->expression.vtype == TYPE_FIELD) {
5328 if (parsewarning(parser, WARN_END_SYS_FIELDS,
5329 "global '%s' hint should not be a field",
5330 parser_tokval(parser)))
5337 if (!nofields && var->expression.vtype == TYPE_FIELD)
5339 /* deal with field declarations */
5340 old = parser_find_field(parser, var->name);
5342 if (parsewarning(parser, WARN_FIELD_REDECLARED, "field `%s` already declared here: %s:%i",
5343 var->name, ast_ctx(old).file, (int)ast_ctx(old).line))
5352 parseerror(parser, "field `%s` already declared here: %s:%i",
5353 var->name, ast_ctx(old).file, ast_ctx(old).line);
5358 if ((OPTS_OPTION_U32(OPTION_STANDARD) == COMPILER_QCC || OPTS_OPTION_U32(OPTION_STANDARD) == COMPILER_FTEQCC) &&
5359 (old = parser_find_global(parser, var->name)))
5361 parseerror(parser, "cannot declare a field and a global of the same name with -std=qcc");
5362 parseerror(parser, "field `%s` already declared here: %s:%i",
5363 var->name, ast_ctx(old).file, ast_ctx(old).line);
5370 /* deal with other globals */
5371 old = parser_find_global(parser, var->name);
5372 if (old && var->expression.vtype == TYPE_FUNCTION && old->vtype == TYPE_FUNCTION)
5374 /* This is a function which had a prototype */
5375 if (!ast_istype(old, ast_value)) {
5376 parseerror(parser, "internal error: prototype is not an ast_value");
5380 proto = (ast_value*)old;
5381 proto->desc = var->desc;
5382 if (!ast_compare_type((ast_expression*)proto, (ast_expression*)var)) {
5383 parseerror(parser, "conflicting types for `%s`, previous declaration was here: %s:%i",
5385 ast_ctx(proto).file, ast_ctx(proto).line);
5389 /* we need the new parameter-names */
5390 for (i = 0; i < vec_size(proto->expression.params); ++i)
5391 ast_value_set_name(proto->expression.params[i], var->expression.params[i]->name);
5392 if (!parser_check_qualifiers(parser, var, proto)) {
5399 proto->expression.flags |= var->expression.flags;
5407 if (parsewarning(parser, WARN_DOUBLE_DECLARATION,
5408 "global `%s` already declared here: %s:%i",
5409 var->name, ast_ctx(old).file, ast_ctx(old).line))
5414 proto = (ast_value*)old;
5415 if (!ast_istype(old, ast_value)) {
5416 parseerror(parser, "internal error: not an ast_value");
5421 if (!parser_check_qualifiers(parser, var, proto)) {
5426 proto->expression.flags |= var->expression.flags;
5430 if (OPTS_OPTION_U32(OPTION_STANDARD) == COMPILER_QCC &&
5431 (old = parser_find_field(parser, var->name)))
5433 parseerror(parser, "cannot declare a field and a global of the same name with -std=qcc");
5434 parseerror(parser, "global `%s` already declared here: %s:%i",
5435 var->name, ast_ctx(old).file, ast_ctx(old).line);
5442 else /* it's not a global */
5444 old = parser_find_local(parser, var->name, vec_size(parser->variables)-1, &isparam);
5445 if (old && !isparam) {
5446 parseerror(parser, "local `%s` already declared here: %s:%i",
5447 var->name, ast_ctx(old).file, (int)ast_ctx(old).line);
5451 old = parser_find_local(parser, var->name, 0, &isparam);
5452 if (old && isparam) {
5453 if (parsewarning(parser, WARN_LOCAL_SHADOWS,
5454 "local `%s` is shadowing a parameter", var->name))
5456 parseerror(parser, "local `%s` already declared here: %s:%i",
5457 var->name, ast_ctx(old).file, (int)ast_ctx(old).line);
5461 if (OPTS_OPTION_U32(OPTION_STANDARD) != COMPILER_GMQCC) {
5469 /* in a noref section we simply bump the usecount */
5470 if (noref || parser->noref)
5474 * Create the global/local, and deal with vector types.
5477 if (var->expression.vtype == TYPE_VECTOR)
5479 else if (var->expression.vtype == TYPE_FIELD &&
5480 var->expression.next->vtype == TYPE_VECTOR)
5484 if (!create_vector_members(var, me)) {
5491 /* deal with global variables, fields, functions */
5492 if (!nofields && var->expression.vtype == TYPE_FIELD && parser->tok != '=') {
5493 var->isfield = true;
5494 vec_push(parser->fields, (ast_expression*)var);
5495 util_htset(parser->htfields, var->name, var);
5497 for (i = 0; i < 3; ++i) {
5498 vec_push(parser->fields, (ast_expression*)me[i]);
5499 util_htset(parser->htfields, me[i]->name, me[i]);
5504 if (!(var->expression.flags & AST_FLAG_ALIAS)) {
5505 parser_addglobal(parser, var->name, (ast_expression*)var);
5507 for (i = 0; i < 3; ++i) {
5508 parser_addglobal(parser, me[i]->name, (ast_expression*)me[i]);
5512 ast_expression *find = parser_find_global(parser, var->desc);
5515 compile_error(parser_ctx(parser), "undeclared variable `%s` for alias `%s`", var->desc, var->name);
5519 if (var->expression.vtype != find->vtype) {
5523 ast_type_to_string(find, ty1, sizeof(ty1));
5524 ast_type_to_string((ast_expression*)var, ty2, sizeof(ty2));
5526 compile_error(parser_ctx(parser), "incompatible types `%s` and `%s` for alias `%s`",
5533 * add alias to aliases table and to corrector
5534 * so corrections can apply for aliases as well.
5536 util_htset(parser->aliases, var->name, find);
5539 * add to corrector so corrections can work
5540 * even for aliases too.
5543 vec_last(parser->correct_variables),
5544 &vec_last(parser->correct_variables_score),
5548 /* generate aliases for vector components */
5552 util_asprintf(&buffer[0], "%s_x", var->desc);
5553 util_asprintf(&buffer[1], "%s_y", var->desc);
5554 util_asprintf(&buffer[2], "%s_z", var->desc);
5556 util_htset(parser->aliases, me[0]->name, parser_find_global(parser, buffer[0]));
5557 util_htset(parser->aliases, me[1]->name, parser_find_global(parser, buffer[1]));
5558 util_htset(parser->aliases, me[2]->name, parser_find_global(parser, buffer[2]));
5565 * add to corrector so corrections can work
5566 * even for aliases too.
5569 vec_last(parser->correct_variables),
5570 &vec_last(parser->correct_variables_score),
5574 vec_last(parser->correct_variables),
5575 &vec_last(parser->correct_variables_score),
5579 vec_last(parser->correct_variables),
5580 &vec_last(parser->correct_variables_score),
5588 /* a static adds itself to be generated like any other global
5589 * but is added to the local namespace instead
5591 char *defname = NULL;
5592 size_t prefix_len, ln;
5594 ln = strlen(parser->function->name);
5595 vec_append(defname, ln, parser->function->name);
5597 vec_append(defname, 2, "::");
5598 /* remember the length up to here */
5599 prefix_len = vec_size(defname);
5601 /* Add it to the local scope */
5602 util_htset(vec_last(parser->variables), var->name, (void*)var);
5606 vec_last(parser->correct_variables),
5607 &vec_last(parser->correct_variables_score),
5611 /* now rename the global */
5612 ln = strlen(var->name);
5613 vec_append(defname, ln, var->name);
5614 ast_value_set_name(var, defname);
5616 /* push it to the to-be-generated globals */
5617 vec_push(parser->globals, (ast_expression*)var);
5619 /* same game for the vector members */
5621 for (i = 0; i < 3; ++i) {
5622 util_htset(vec_last(parser->variables), me[i]->name, (void*)(me[i]));
5626 vec_last(parser->correct_variables),
5627 &vec_last(parser->correct_variables_score),
5631 vec_shrinkto(defname, prefix_len);
5632 ln = strlen(me[i]->name);
5633 vec_append(defname, ln, me[i]->name);
5634 ast_member_set_name(me[i], defname);
5636 vec_push(parser->globals, (ast_expression*)me[i]);
5641 vec_push(localblock->locals, var);
5642 parser_addlocal(parser, var->name, (ast_expression*)var);
5644 for (i = 0; i < 3; ++i) {
5645 parser_addlocal(parser, me[i]->name, (ast_expression*)me[i]);
5646 ast_block_collect(localblock, (ast_expression*)me[i]);
5652 me[0] = me[1] = me[2] = NULL;
5657 if (var->expression.vtype == TYPE_ARRAY) {
5659 util_snprintf(name, sizeof(name), "%s##SET", var->name);
5660 if (!parser_create_array_setter(parser, var, name))
5662 util_snprintf(name, sizeof(name), "%s##GET", var->name);
5663 if (!parser_create_array_getter(parser, var, var->expression.next, name))
5666 else if (!localblock && !nofields &&
5667 var->expression.vtype == TYPE_FIELD &&
5668 var->expression.next->vtype == TYPE_ARRAY)
5671 ast_expression *telem;
5673 ast_value *array = (ast_value*)var->expression.next;
5675 if (!ast_istype(var->expression.next, ast_value)) {
5676 parseerror(parser, "internal error: field element type must be an ast_value");
5680 util_snprintf(name, sizeof(name), "%s##SETF", var->name);
5681 if (!parser_create_array_field_setter(parser, array, name))
5684 telem = ast_type_copy(ast_ctx(var), array->expression.next);
5685 tfield = ast_value_new(ast_ctx(var), "<.type>", TYPE_FIELD);
5686 tfield->expression.next = telem;
5687 util_snprintf(name, sizeof(name), "%s##GETFP", var->name);
5688 if (!parser_create_array_getter(parser, array, (ast_expression*)tfield, name)) {
5696 if (parser->tok == ';') {
5697 ast_delete(basetype);
5698 if (!parser_next(parser)) {
5699 parseerror(parser, "error after variable declaration");
5705 if (parser->tok == ',')
5709 if (!var || (!localblock && !nofields && basetype->expression.vtype == TYPE_FIELD)) {
5712 parseerror(parser, "missing comma or semicolon while parsing variables");
5716 if (localblock && OPTS_OPTION_U32(OPTION_STANDARD) == COMPILER_QCC) {
5717 if (parsewarning(parser, WARN_LOCAL_CONSTANTS,
5718 "initializing expression turns variable `%s` into a constant in this standard",
5725 if (parser->tok != '{' || var->expression.vtype != TYPE_FUNCTION) {
5726 if (parser->tok != '=') {
5727 const char *obtain = parser_tokval(parser);
5728 if (!strcmp(obtain, "}")) {
5729 parser->diagnostic = DIAGNOSTIC_SEMICOLON;
5730 parseerror(parser, "expected semicolon");
5732 parseerror(parser, "missing initializer");
5736 if (!parser_next(parser)) {
5737 parseerror(parser, "error parsing initializer");
5741 else if (OPTS_OPTION_U32(OPTION_STANDARD) == COMPILER_QCC) {
5742 parseerror(parser, "expected '=' before function body in this standard");
5745 if (parser->tok == '#') {
5746 ast_function *func = NULL;
5747 ast_value *number = NULL;
5753 parseerror(parser, "cannot declare builtins within functions");
5756 if (var->expression.vtype != TYPE_FUNCTION) {
5757 parseerror(parser, "unexpected builtin number, '%s' is not a function", var->name);
5760 if (!parser_next(parser)) {
5761 parseerror(parser, "expected builtin number");
5765 if (OPTS_FLAG(EXPRESSIONS_FOR_BUILTINS)) {
5766 number = (ast_value*)parse_expression_leave(parser, true, false, false);
5768 parseerror(parser, "builtin number expected");
5771 if (!ast_istype(number, ast_value) || !number->hasvalue || number->cvq != CV_CONST)
5774 parseerror(parser, "builtin number must be a compile time constant");
5777 if (number->expression.vtype == TYPE_INTEGER)
5778 builtin_num = number->constval.vint;
5779 else if (number->expression.vtype == TYPE_FLOAT)
5780 builtin_num = number->constval.vfloat;
5783 parseerror(parser, "builtin number must be an integer constant");
5788 fractional = modff(builtin_num, &integral);
5789 if (builtin_num < 0 || fractional != 0) {
5790 parseerror(parser, "builtin number must be an integer greater than zero");
5794 /* we only want the integral part anyways */
5795 builtin_num = integral;
5796 } else if (parser->tok == TOKEN_INTCONST) {
5797 builtin_num = parser_token(parser)->constval.i;
5799 parseerror(parser, "builtin number must be a compile time constant");
5803 if (var->hasvalue) {
5804 (void)!parsewarning(parser, WARN_DOUBLE_DECLARATION,
5805 "builtin `%s` has already been defined\n"
5806 " -> previous declaration here: %s:%i",
5807 var->name, ast_ctx(var).file, (int)ast_ctx(var).line);
5811 func = ast_function_new(ast_ctx(var), var->name, var);
5813 parseerror(parser, "failed to allocate function for `%s`", var->name);
5816 vec_push(parser->functions, func);
5818 func->builtin = -builtin_num-1;
5821 if (OPTS_FLAG(EXPRESSIONS_FOR_BUILTINS)
5822 ? (parser->tok != ',' && parser->tok != ';')
5823 : (!parser_next(parser)))
5825 parseerror(parser, "expected comma or semicolon");
5827 ast_function_delete(func);
5828 var->constval.vfunc = NULL;
5832 else if (var->expression.vtype == TYPE_ARRAY && parser->tok == '{')
5835 /* Note that fteqcc and most others don't even *have*
5836 * local arrays, so this is not a high priority.
5838 parseerror(parser, "TODO: initializers for local arrays");
5842 static ast_expression* parse_expression_leave(parser_t *parser, bool stopatcomma, bool truthvalue, bool with_labels);
5844 parseerror(parser, "TODO: initializing global arrays is not supported yet!");
5847 else if (var->expression.vtype == TYPE_FUNCTION && (parser->tok == '{' || parser->tok == '['))
5850 parseerror(parser, "cannot declare functions within functions");
5855 ast_ctx(proto) = parser_ctx(parser);
5857 if (!parse_function_body(parser, var))
5859 ast_delete(basetype);
5860 for (i = 0; i < vec_size(parser->gotos); ++i)
5861 parseerror(parser, "undefined label: `%s`", parser->gotos[i]->name);
5862 vec_free(parser->gotos);
5863 vec_free(parser->labels);
5866 cexp = parse_expression_leave(parser, true, false, false);
5871 cval = (ast_value*)cexp;
5872 if (cval != parser->nil &&
5873 (!ast_istype(cval, ast_value) || ((!cval->hasvalue || cval->cvq != CV_CONST) && !cval->isfield))
5876 parseerror(parser, "cannot initialize a global constant variable with a non-constant expression");
5880 if (!OPTS_FLAG(INITIALIZED_NONCONSTANTS) &&
5881 qualifier != CV_VAR)
5883 var->cvq = CV_CONST;
5885 if (cval == parser->nil)
5886 var->expression.flags |= AST_FLAG_INITIALIZED;
5889 var->hasvalue = true;
5890 if (cval->expression.vtype == TYPE_STRING)
5891 var->constval.vstring = parser_strdup(cval->constval.vstring);
5892 else if (cval->expression.vtype == TYPE_FIELD)
5893 var->constval.vfield = cval;
5895 memcpy(&var->constval, &cval->constval, sizeof(var->constval));
5901 shunt sy = { NULL, NULL, NULL, NULL };
5904 vec_push(sy.out, syexp(ast_ctx(var), (ast_expression*)var));
5905 vec_push(sy.out, syexp(ast_ctx(cexp), (ast_expression*)cexp));
5906 vec_push(sy.ops, syop(ast_ctx(var), parser->assign_op));
5907 if (!parser_sy_apply_operator(parser, &sy))
5910 if (vec_size(sy.out) != 1 && vec_size(sy.ops) != 0)
5911 parseerror(parser, "internal error: leaked operands");
5912 if (!ast_block_add_expr(localblock, (ast_expression*)sy.out[0].out))
5923 if (parser->tok == ',') {
5924 if (!parser_next(parser)) {
5925 parseerror(parser, "expected another variable");
5929 if (parser->tok != TOKEN_IDENT) {
5930 parseerror(parser, "expected another variable");
5933 var = ast_value_copy(basetype);
5935 ast_value_set_name(var, parser_tokval(parser));
5936 if (!parser_next(parser)) {
5937 parseerror(parser, "error parsing variable declaration");
5943 if (parser->tok != ';') {
5944 parser->diagnostic = DIAGNOSTIC_SEMICOLON;
5945 parseerror(parser, "missing semicolon after variables");
5949 if (!parser_next(parser)) {
5950 parseerror(parser, "parse error after variable declaration");
5954 ast_delete(basetype);
5958 if (cleanvar && var)
5960 ast_delete(basetype);
5964 ast_delete(basetype);
5965 if (cleanvar && var)
5967 if (me[0]) ast_member_delete(me[0]);
5968 if (me[1]) ast_member_delete(me[1]);
5969 if (me[2]) ast_member_delete(me[2]);
5973 static bool parser_global_statement(parser_t *parser)
5977 bool is_static = false;
5978 uint32_t qflags = 0;
5979 ast_value *istype = NULL;
5980 char *vstring = NULL;
5982 if (parser->tok == TOKEN_IDENT)
5983 istype = parser_find_typedef(parser, parser_tokval(parser), 0);
5985 if (istype || parser->tok == TOKEN_TYPENAME || parser->tok == '.')
5987 return parse_variable(parser, NULL, false, CV_NONE, istype, false, false, 0, NULL);
5989 else if (parse_qualifiers(parser, false, &cvq, &noref, &is_static, &qflags, &vstring))
5991 if (cvq == CV_WRONG)
5993 return parse_variable(parser, NULL, true, cvq, NULL, noref, is_static, qflags, vstring);
5995 else if (parser->tok == TOKEN_IDENT && !strcmp(parser_tokval(parser), "enum"))
5997 return parse_enum(parser);
5999 else if (parser->tok == TOKEN_KEYWORD)
6001 if (!strcmp(parser_tokval(parser), "typedef")) {
6002 if (!parser_next(parser)) {
6003 parseerror(parser, "expected type definition after 'typedef'");
6006 return parse_typedef(parser);
6008 parseerror(parser, "unrecognized keyword `%s`", parser_tokval(parser));
6011 else if (parser->tok == '#')
6013 return parse_pragma(parser);
6015 else if (parser->tok == '$')
6017 if (!parser_next(parser)) {
6018 parseerror(parser, "parse error");
6024 parser->diagnostic = DIAGNOSTIC_UNEXPECTED_TOKEN;
6025 parseerror(parser, "unexpected token: `%s`", parser->lex->tok.value);
6031 static uint16_t progdefs_crc_sum(uint16_t old, const char *str)
6033 return util_crc16(old, str, strlen(str));
6036 static void progdefs_crc_file(const char *str)
6038 /* write to progdefs.h here */
6042 static uint16_t progdefs_crc_both(uint16_t old, const char *str)
6044 old = progdefs_crc_sum(old, str);
6045 progdefs_crc_file(str);
6049 static void generate_checksum(parser_t *parser)
6051 uint16_t crc = 0xFFFF;
6055 crc = progdefs_crc_both(crc, "\n/* file generated by qcc, do not modify */\n\ntypedef struct\n{");
6056 crc = progdefs_crc_sum(crc, "\tint\tpad[28];\n");
6058 progdefs_crc_file("\tint\tpad;\n");
6059 progdefs_crc_file("\tint\tofs_return[3];\n");
6060 progdefs_crc_file("\tint\tofs_parm0[3];\n");
6061 progdefs_crc_file("\tint\tofs_parm1[3];\n");
6062 progdefs_crc_file("\tint\tofs_parm2[3];\n");
6063 progdefs_crc_file("\tint\tofs_parm3[3];\n");
6064 progdefs_crc_file("\tint\tofs_parm4[3];\n");
6065 progdefs_crc_file("\tint\tofs_parm5[3];\n");
6066 progdefs_crc_file("\tint\tofs_parm6[3];\n");
6067 progdefs_crc_file("\tint\tofs_parm7[3];\n");
6069 for (i = 0; i < parser->crc_globals; ++i) {
6070 if (!ast_istype(parser->globals[i], ast_value))
6072 value = (ast_value*)(parser->globals[i]);
6073 switch (value->expression.vtype) {
6074 case TYPE_FLOAT: crc = progdefs_crc_both(crc, "\tfloat\t"); break;
6075 case TYPE_VECTOR: crc = progdefs_crc_both(crc, "\tvec3_t\t"); break;
6076 case TYPE_STRING: crc = progdefs_crc_both(crc, "\tstring_t\t"); break;
6077 case TYPE_FUNCTION: crc = progdefs_crc_both(crc, "\tfunc_t\t"); break;
6079 crc = progdefs_crc_both(crc, "\tint\t");
6082 crc = progdefs_crc_both(crc, value->name);
6083 crc = progdefs_crc_both(crc, ";\n");
6085 crc = progdefs_crc_both(crc, "} globalvars_t;\n\ntypedef struct\n{\n");
6086 for (i = 0; i < parser->crc_fields; ++i) {
6087 if (!ast_istype(parser->fields[i], ast_value))
6089 value = (ast_value*)(parser->fields[i]);
6090 switch (value->expression.next->vtype) {
6091 case TYPE_FLOAT: crc = progdefs_crc_both(crc, "\tfloat\t"); break;
6092 case TYPE_VECTOR: crc = progdefs_crc_both(crc, "\tvec3_t\t"); break;
6093 case TYPE_STRING: crc = progdefs_crc_both(crc, "\tstring_t\t"); break;
6094 case TYPE_FUNCTION: crc = progdefs_crc_both(crc, "\tfunc_t\t"); break;
6096 crc = progdefs_crc_both(crc, "\tint\t");
6099 crc = progdefs_crc_both(crc, value->name);
6100 crc = progdefs_crc_both(crc, ";\n");
6102 crc = progdefs_crc_both(crc, "} entvars_t;\n\n");
6104 parser->code->crc = crc;
6107 parser_t *parser_create()
6113 parser = (parser_t*)mem_a(sizeof(parser_t));
6117 memset(parser, 0, sizeof(*parser));
6119 if (!(parser->code = code_init())) {
6124 for (i = 0; i < operator_count; ++i) {
6125 if (operators[i].id == opid1('=')) {
6126 parser->assign_op = operators+i;
6130 if (!parser->assign_op) {
6131 printf("internal error: initializing parser: failed to find assign operator\n");
6136 vec_push(parser->variables, parser->htfields = util_htnew(PARSER_HT_SIZE));
6137 vec_push(parser->variables, parser->htglobals = util_htnew(PARSER_HT_SIZE));
6138 vec_push(parser->typedefs, util_htnew(TYPEDEF_HT_SIZE));
6139 vec_push(parser->_blocktypedefs, 0);
6141 parser->aliases = util_htnew(PARSER_HT_SIZE);
6143 parser->ht_imm_string = util_htnew(512);
6146 vec_push(parser->correct_variables, correct_trie_new());
6147 vec_push(parser->correct_variables_score, NULL);
6149 empty_ctx.file = "<internal>";
6151 parser->nil = ast_value_new(empty_ctx, "nil", TYPE_NIL);
6152 parser->nil->cvq = CV_CONST;
6153 if (OPTS_FLAG(UNTYPED_NIL))
6154 util_htset(parser->htglobals, "nil", (void*)parser->nil);
6156 parser->max_param_count = 1;
6158 parser->const_vec[0] = ast_value_new(empty_ctx, "<vector.x>", TYPE_NOEXPR);
6159 parser->const_vec[1] = ast_value_new(empty_ctx, "<vector.y>", TYPE_NOEXPR);
6160 parser->const_vec[2] = ast_value_new(empty_ctx, "<vector.z>", TYPE_NOEXPR);
6162 if (OPTS_OPTION_BOOL(OPTION_ADD_INFO)) {
6163 parser->reserved_version = ast_value_new(empty_ctx, "reserved:version", TYPE_STRING);
6164 parser->reserved_version->cvq = CV_CONST;
6165 parser->reserved_version->hasvalue = true;
6166 parser->reserved_version->expression.flags |= AST_FLAG_INCLUDE_DEF;
6167 parser->reserved_version->constval.vstring = util_strdup(GMQCC_FULL_VERSION_STRING);
6169 parser->reserved_version = NULL;
6175 static bool parser_compile(parser_t *parser)
6177 /* initial lexer/parser state */
6178 parser->lex->flags.noops = true;
6180 if (parser_next(parser))
6182 while (parser->tok != TOKEN_EOF && parser->tok < TOKEN_ERROR)
6184 if (!parser_global_statement(parser)) {
6185 parser->diagnostic = DIAGNOSTIC_NULL;
6186 if (parser->tok == TOKEN_EOF) {
6187 parseerror(parser, "unexpected eof");
6188 } else if (compile_errors) {
6189 parseerror(parser, "there have been errors, bailing out");
6191 lex_close(parser->lex);
6197 parseerror(parser, "parse error");
6198 lex_close(parser->lex);
6203 lex_close(parser->lex);
6206 return !compile_errors;
6209 bool parser_compile_file(parser_t *parser, const char *filename)
6211 parser->lex = lex_open(filename);
6213 con_err("failed to open file \"%s\"\n", filename);
6216 return parser_compile(parser);
6219 bool parser_compile_string(parser_t *parser, const char *name, const char *str, size_t len)
6221 parser->lex = lex_open_string(str, len, name);
6223 con_err("failed to create lexer for string \"%s\"\n", name);
6226 return parser_compile(parser);
6229 static void parser_remove_ast(parser_t *parser)
6232 if (parser->ast_cleaned)
6234 parser->ast_cleaned = true;
6235 for (i = 0; i < vec_size(parser->accessors); ++i) {
6236 ast_delete(parser->accessors[i]->constval.vfunc);
6237 parser->accessors[i]->constval.vfunc = NULL;
6238 ast_delete(parser->accessors[i]);
6240 for (i = 0; i < vec_size(parser->functions); ++i) {
6241 ast_delete(parser->functions[i]);
6243 for (i = 0; i < vec_size(parser->imm_vector); ++i) {
6244 ast_delete(parser->imm_vector[i]);
6246 for (i = 0; i < vec_size(parser->imm_string); ++i) {
6247 ast_delete(parser->imm_string[i]);
6249 for (i = 0; i < vec_size(parser->imm_float); ++i) {
6250 ast_delete(parser->imm_float[i]);
6252 for (i = 0; i < vec_size(parser->fields); ++i) {
6253 ast_delete(parser->fields[i]);
6255 for (i = 0; i < vec_size(parser->globals); ++i) {
6256 ast_delete(parser->globals[i]);
6258 vec_free(parser->accessors);
6259 vec_free(parser->functions);
6260 vec_free(parser->imm_vector);
6261 vec_free(parser->imm_string);
6262 util_htdel(parser->ht_imm_string);
6263 vec_free(parser->imm_float);
6264 vec_free(parser->globals);
6265 vec_free(parser->fields);
6267 for (i = 0; i < vec_size(parser->variables); ++i)
6268 util_htdel(parser->variables[i]);
6269 vec_free(parser->variables);
6270 vec_free(parser->_blocklocals);
6271 vec_free(parser->_locals);
6274 for (i = 0; i < vec_size(parser->correct_variables); ++i) {
6275 correct_del(parser->correct_variables[i], parser->correct_variables_score[i]);
6277 vec_free(parser->correct_variables);
6278 vec_free(parser->correct_variables_score);
6281 for (i = 0; i < vec_size(parser->_typedefs); ++i)
6282 ast_delete(parser->_typedefs[i]);
6283 vec_free(parser->_typedefs);
6284 for (i = 0; i < vec_size(parser->typedefs); ++i)
6285 util_htdel(parser->typedefs[i]);
6286 vec_free(parser->typedefs);
6287 vec_free(parser->_blocktypedefs);
6289 vec_free(parser->_block_ctx);
6291 vec_free(parser->labels);
6292 vec_free(parser->gotos);
6293 vec_free(parser->breaks);
6294 vec_free(parser->continues);
6296 ast_value_delete(parser->nil);
6298 ast_value_delete(parser->const_vec[0]);
6299 ast_value_delete(parser->const_vec[1]);
6300 ast_value_delete(parser->const_vec[2]);
6302 util_htdel(parser->aliases);
6303 intrin_intrinsics_destroy(parser);
6306 void parser_cleanup(parser_t *parser)
6308 parser_remove_ast(parser);
6309 code_cleanup(parser->code);
6314 bool parser_finish(parser_t *parser, const char *output)
6320 if (compile_errors) {
6321 con_out("*** there were compile errors\n");
6325 ir = ir_builder_new("gmqcc_out");
6327 con_out("failed to allocate builder\n");
6331 for (i = 0; i < vec_size(parser->fields); ++i) {
6334 if (!ast_istype(parser->fields[i], ast_value))
6336 field = (ast_value*)parser->fields[i];
6337 hasvalue = field->hasvalue;
6338 field->hasvalue = false;
6339 if (!ast_global_codegen((ast_value*)field, ir, true)) {
6340 con_out("failed to generate field %s\n", field->name);
6341 ir_builder_delete(ir);
6346 ast_expression *subtype;
6347 field->hasvalue = true;
6348 subtype = field->expression.next;
6349 ifld = ir_builder_create_field(ir, field->name, subtype->vtype);
6350 if (subtype->vtype == TYPE_FIELD)
6351 ifld->fieldtype = subtype->next->vtype;
6352 else if (subtype->vtype == TYPE_FUNCTION)
6353 ifld->outtype = subtype->next->vtype;
6354 (void)!ir_value_set_field(field->ir_v, ifld);
6357 for (i = 0; i < vec_size(parser->globals); ++i) {
6359 if (!ast_istype(parser->globals[i], ast_value))
6361 asvalue = (ast_value*)(parser->globals[i]);
6362 if (!asvalue->uses && !asvalue->hasvalue && asvalue->expression.vtype != TYPE_FUNCTION) {
6363 retval = retval && !compile_warning(ast_ctx(asvalue), WARN_UNUSED_VARIABLE,
6364 "unused global: `%s`", asvalue->name);
6366 if (!ast_global_codegen(asvalue, ir, false)) {
6367 con_out("failed to generate global %s\n", asvalue->name);
6368 ir_builder_delete(ir);
6372 /* Build function vararg accessor ast tree now before generating
6373 * immediates, because the accessors may add new immediates
6375 for (i = 0; i < vec_size(parser->functions); ++i) {
6376 ast_function *f = parser->functions[i];
6378 if (parser->max_param_count > vec_size(f->vtype->expression.params)) {
6379 f->varargs->expression.count = parser->max_param_count - vec_size(f->vtype->expression.params);
6380 if (!parser_create_array_setter_impl(parser, f->varargs)) {
6381 con_out("failed to generate vararg setter for %s\n", f->name);
6382 ir_builder_delete(ir);
6385 if (!parser_create_array_getter_impl(parser, f->varargs)) {
6386 con_out("failed to generate vararg getter for %s\n", f->name);
6387 ir_builder_delete(ir);
6391 ast_delete(f->varargs);
6396 /* Now we can generate immediates */
6397 for (i = 0; i < vec_size(parser->imm_float); ++i) {
6398 if (!ast_global_codegen(parser->imm_float[i], ir, false)) {
6399 con_out("failed to generate global %s\n", parser->imm_float[i]->name);
6400 ir_builder_delete(ir);
6404 for (i = 0; i < vec_size(parser->imm_string); ++i) {
6405 if (!ast_global_codegen(parser->imm_string[i], ir, false)) {
6406 con_out("failed to generate global %s\n", parser->imm_string[i]->name);
6407 ir_builder_delete(ir);
6411 for (i = 0; i < vec_size(parser->imm_vector); ++i) {
6412 if (!ast_global_codegen(parser->imm_vector[i], ir, false)) {
6413 con_out("failed to generate global %s\n", parser->imm_vector[i]->name);
6414 ir_builder_delete(ir);
6418 for (i = 0; i < vec_size(parser->globals); ++i) {
6420 if (!ast_istype(parser->globals[i], ast_value))
6422 asvalue = (ast_value*)(parser->globals[i]);
6423 if (!(asvalue->expression.flags & AST_FLAG_INITIALIZED))
6425 if (asvalue->cvq == CV_CONST && !asvalue->hasvalue)
6426 (void)!compile_warning(ast_ctx(asvalue), WARN_UNINITIALIZED_CONSTANT,
6427 "uninitialized constant: `%s`",
6429 else if ((asvalue->cvq == CV_NONE || asvalue->cvq == CV_CONST) && !asvalue->hasvalue)
6430 (void)!compile_warning(ast_ctx(asvalue), WARN_UNINITIALIZED_GLOBAL,
6431 "uninitialized global: `%s`",
6434 if (!ast_generate_accessors(asvalue, ir)) {
6435 ir_builder_delete(ir);
6439 for (i = 0; i < vec_size(parser->fields); ++i) {
6441 asvalue = (ast_value*)(parser->fields[i]->next);
6443 if (!ast_istype((ast_expression*)asvalue, ast_value))
6445 if (asvalue->expression.vtype != TYPE_ARRAY)
6447 if (!ast_generate_accessors(asvalue, ir)) {
6448 ir_builder_delete(ir);
6452 if (parser->reserved_version &&
6453 !ast_global_codegen(parser->reserved_version, ir, false))
6455 con_out("failed to generate reserved::version");
6456 ir_builder_delete(ir);
6459 for (i = 0; i < vec_size(parser->functions); ++i) {
6460 ast_function *f = parser->functions[i];
6461 if (!ast_function_codegen(f, ir)) {
6462 con_out("failed to generate function %s\n", f->name);
6463 ir_builder_delete(ir);
6468 generate_checksum(parser);
6469 if (OPTS_OPTION_BOOL(OPTION_DUMP))
6470 ir_builder_dump(ir, con_out);
6471 for (i = 0; i < vec_size(parser->functions); ++i) {
6472 if (!ir_function_finalize(parser->functions[i]->ir_func)) {
6473 con_out("failed to finalize function %s\n", parser->functions[i]->name);
6474 ir_builder_delete(ir);
6478 parser_remove_ast(parser);
6480 if (compile_Werrors) {
6481 con_out("*** there were warnings treated as errors\n");
6482 compile_show_werrors();
6487 if (OPTS_OPTION_BOOL(OPTION_DUMPFIN))
6488 ir_builder_dump(ir, con_out);
6490 if (!ir_builder_generate(parser->code, ir, output)) {
6491 con_out("*** failed to generate output file\n");
6492 ir_builder_delete(ir);
6496 diagnostic_destroy();
6497 ir_builder_delete(ir);