16 MEM_VECTOR_MAKE(varentry_t, globals);
17 MEM_VECTOR_MAKE(varentry_t, fields);
18 MEM_VECTOR_MAKE(ast_function*, functions);
19 MEM_VECTOR_MAKE(ast_value*, imm_float);
20 MEM_VECTOR_MAKE(ast_value*, imm_string);
21 MEM_VECTOR_MAKE(ast_value*, imm_vector);
23 ast_value *imm_float_zero;
24 ast_value *imm_vector_zero;
29 ast_function *function;
30 MEM_VECTOR_MAKE(varentry_t, locals);
35 /* TYPE_FIELD -> parser_find_fields is used instead of find_var
36 * TODO: TYPE_VECTOR -> x, y and z are accepted in the gmqcc standard
37 * anything else: type error
42 MEM_VEC_FUNCTIONS(parser_t, varentry_t, globals)
43 MEM_VEC_FUNCTIONS(parser_t, varentry_t, fields)
44 MEM_VEC_FUNCTIONS(parser_t, ast_value*, imm_float)
45 MEM_VEC_FUNCTIONS(parser_t, ast_value*, imm_string)
46 MEM_VEC_FUNCTIONS(parser_t, ast_value*, imm_vector)
47 MEM_VEC_FUNCTIONS(parser_t, varentry_t, locals)
48 MEM_VEC_FUNCTIONS(parser_t, ast_function*, functions)
50 static bool GMQCC_WARN parser_pop_local(parser_t *parser);
51 static bool parse_variable(parser_t *parser, ast_block *localblock);
52 static ast_block* parse_block(parser_t *parser, bool warnreturn);
53 static bool parse_block_into(parser_t *parser, ast_block *block, bool warnreturn);
54 static ast_expression* parse_statement_or_block(parser_t *parser);
55 static ast_expression* parse_expression_leave(parser_t *parser, bool stopatcomma);
56 static ast_expression* parse_expression(parser_t *parser, bool stopatcomma);
58 static void parseerror(parser_t *parser, const char *fmt, ...)
65 vprintmsg(LVL_ERROR, parser->lex->tok.ctx.file, parser->lex->tok.ctx.line, "parse error", fmt, ap);
69 /* returns true if it counts as an error */
70 static bool GMQCC_WARN parsewarning(parser_t *parser, int warntype, const char *fmt, ...)
73 int lvl = LVL_WARNING;
75 if (!OPTS_WARN(warntype))
84 vprintmsg(lvl, parser->lex->tok.ctx.file, parser->lex->tok.ctx.line, "warning", fmt, ap);
90 static bool GMQCC_WARN genwarning(lex_ctx ctx, int warntype, const char *fmt, ...)
93 int lvl = LVL_WARNING;
95 if (!OPTS_WARN(warntype))
102 vprintmsg(lvl, ctx.file, ctx.line, "warning", fmt, ap);
108 /**********************************************************************
109 * some maths used for constant folding
112 vector vec3_add(vector a, vector b)
121 vector vec3_sub(vector a, vector b)
130 qcfloat vec3_mulvv(vector a, vector b)
132 return (a.x * b.x + a.y * b.y + a.z * b.z);
135 vector vec3_mulvf(vector a, float b)
144 /**********************************************************************
148 bool parser_next(parser_t *parser)
150 /* lex_do kills the previous token */
151 parser->tok = lex_do(parser->lex);
152 if (parser->tok == TOKEN_EOF)
154 if (parser->tok >= TOKEN_ERROR) {
155 parseerror(parser, "lex error");
161 #define parser_tokval(p) ((p)->lex->tok.value)
162 #define parser_token(p) (&((p)->lex->tok))
163 #define parser_ctx(p) ((p)->lex->tok.ctx)
165 static ast_value* parser_const_float(parser_t *parser, double d)
169 for (i = 0; i < parser->imm_float_count; ++i) {
170 if (parser->imm_float[i]->constval.vfloat == d)
171 return parser->imm_float[i];
173 out = ast_value_new(parser_ctx(parser), "#IMMEDIATE", TYPE_FLOAT);
175 out->constval.vfloat = d;
176 if (!parser_t_imm_float_add(parser, out)) {
177 ast_value_delete(out);
183 static ast_value* parser_const_float_0(parser_t *parser)
185 if (!parser->imm_float_zero)
186 parser->imm_float_zero = parser_const_float(parser, 0);
187 return parser->imm_float_zero;
190 static char *parser_strdup(const char *str)
193 /* actually dup empty strings */
194 char *out = mem_a(1);
198 return util_strdup(str);
201 static ast_value* parser_const_string(parser_t *parser, const char *str)
205 for (i = 0; i < parser->imm_string_count; ++i) {
206 if (!strcmp(parser->imm_string[i]->constval.vstring, str))
207 return parser->imm_string[i];
209 out = ast_value_new(parser_ctx(parser), "#IMMEDIATE", TYPE_STRING);
211 out->constval.vstring = parser_strdup(str);
212 if (!parser_t_imm_string_add(parser, out)) {
213 ast_value_delete(out);
219 static ast_value* parser_const_vector(parser_t *parser, vector v)
223 for (i = 0; i < parser->imm_vector_count; ++i) {
224 if (!memcmp(&parser->imm_vector[i]->constval.vvec, &v, sizeof(v)))
225 return parser->imm_vector[i];
227 out = ast_value_new(parser_ctx(parser), "#IMMEDIATE", TYPE_VECTOR);
229 out->constval.vvec = v;
230 if (!parser_t_imm_vector_add(parser, out)) {
231 ast_value_delete(out);
237 static ast_value* parser_const_vector_f(parser_t *parser, float x, float y, float z)
243 return parser_const_vector(parser, v);
246 static ast_value* parser_const_vector_0(parser_t *parser)
248 if (!parser->imm_vector_zero)
249 parser->imm_vector_zero = parser_const_vector_f(parser, 0, 0, 0);
250 return parser->imm_vector_zero;
253 static ast_expression* parser_find_field(parser_t *parser, const char *name)
256 for (i = 0; i < parser->fields_count; ++i) {
257 if (!strcmp(parser->fields[i].name, name))
258 return parser->fields[i].var;
263 static ast_expression* parser_find_global(parser_t *parser, const char *name)
266 for (i = 0; i < parser->globals_count; ++i) {
267 if (!strcmp(parser->globals[i].name, name))
268 return parser->globals[i].var;
273 static ast_expression* parser_find_param(parser_t *parser, const char *name)
277 if (!parser->function)
279 fun = parser->function->vtype;
280 for (i = 0; i < fun->expression.params_count; ++i) {
281 if (!strcmp(fun->expression.params[i]->name, name))
282 return (ast_expression*)(fun->expression.params[i]);
287 static ast_expression* parser_find_local(parser_t *parser, const char *name, size_t upto, bool *isparam)
291 for (i = parser->locals_count; i > upto;) {
293 if (!strcmp(parser->locals[i].name, name))
294 return parser->locals[i].var;
297 return parser_find_param(parser, name);
300 static ast_expression* parser_find_var(parser_t *parser, const char *name)
304 v = parser_find_local(parser, name, 0, &dummy);
305 if (!v) v = parser_find_global(parser, name);
310 MEM_VECTOR_MAKE(ast_value*, p);
312 MEM_VEC_FUNCTIONS(paramlist_t, ast_value*, p)
314 static ast_value *parse_type(parser_t *parser, int basetype, bool *isfunc)
318 lex_ctx ctx = parser_ctx(parser);
319 int vtype = basetype;
322 bool variadic = false;
324 MEM_VECTOR_INIT(¶ms, p);
328 if (parser->tok == '(') {
333 bool isfield = false;
334 bool isfuncparam = false;
336 if (!parser_next(parser))
339 if (parser->tok == ')')
342 if (parser->tok == '.') {
344 if (!parser_next(parser)) {
345 parseerror(parser, "expected field parameter type");
350 if (parser->tok == TOKEN_DOTS) {
353 if (!parser_next(parser))
355 if (parser->tok != ')') {
356 parseerror(parser, "`...` must be the last parameter of a variadic function declaration");
359 if (opts_standard == COMPILER_QCC) {
360 if (parsewarning(parser, WARN_EXTENSIONS, "variadic functions are not available in this standard"))
366 temptype = parser_token(parser)->constval.t;
367 if (!parser_next(parser))
370 param = parse_type(parser, temptype, &isfuncparam);
375 if (parser->tok == TOKEN_IDENT) {
376 /* named parameter */
377 if (!ast_value_set_name(param, parser_tokval(parser)))
379 if (!parser_next(parser))
383 /* This comes before the isfield part! */
385 ast_value *fval = ast_value_new(ast_ctx(param), param->name, TYPE_FUNCTION);
390 fval->expression.next = (ast_expression*)param;
391 MEM_VECTOR_MOVE(¶m->expression, params, &fval->expression, params);
392 fval->expression.variadic = param->expression.variadic;
397 fld = ast_value_new(ctx, param->name, TYPE_FIELD);
398 fld->expression.next = (ast_expression*)param;
402 if (!paramlist_t_p_add(¶ms, param)) {
403 parseerror(parser, "Out of memory while parsing typename");
407 if (parser->tok == ',')
409 if (parser->tok == ')')
411 parseerror(parser, "Unexpected token");
414 if (!parser_next(parser))
418 if (params.p_count > 8)
419 parseerror(parser, "more than 8 parameters are currently not supported");
421 var = ast_value_new(ctx, "<unnamed>", vtype);
424 var->expression.variadic = variadic;
425 MEM_VECTOR_MOVE(¶ms, p, &var->expression, params);
428 for (i = 0; i < params.p_count; ++i)
429 ast_value_delete(params.p[i]);
430 MEM_VECTOR_CLEAR(¶ms, p);
436 size_t etype; /* 0 = expression, others are operators */
440 ast_block *block; /* for commas and function calls */
445 MEM_VECTOR_MAKE(sy_elem, out);
446 MEM_VECTOR_MAKE(sy_elem, ops);
448 MEM_VEC_FUNCTIONS(shunt, sy_elem, out)
449 MEM_VEC_FUNCTIONS(shunt, sy_elem, ops)
451 static sy_elem syexp(lex_ctx ctx, ast_expression *v) {
462 static sy_elem syblock(lex_ctx ctx, ast_block *v) {
466 e.out = (ast_expression*)v;
473 static sy_elem syop(lex_ctx ctx, const oper_info *op) {
475 e.etype = 1 + (op - operators);
484 static sy_elem syparen(lex_ctx ctx, int p, size_t off) {
496 # define DEBUGSHUNTDO(x) x
498 # define DEBUGSHUNTDO(x)
501 static bool parser_sy_pop(parser_t *parser, shunt *sy)
505 ast_expression *out = NULL;
506 ast_expression *exprs[3];
507 ast_block *blocks[3];
508 ast_value *asvalue[3];
510 qcint generated_op = 0;
512 if (!sy->ops_count) {
513 parseerror(parser, "internal error: missing operator");
517 if (sy->ops[sy->ops_count-1].paren) {
518 parseerror(parser, "unmatched parenthesis");
522 op = &operators[sy->ops[sy->ops_count-1].etype - 1];
523 ctx = sy->ops[sy->ops_count-1].ctx;
525 DEBUGSHUNTDO(con_out("apply %s\n", op->op));
527 if (sy->out_count < op->operands) {
528 parseerror(parser, "internal error: not enough operands: %i (operator %s (%i))", sy->out_count,
529 op->op, (int)op->id);
535 sy->out_count -= op->operands;
536 for (i = 0; i < op->operands; ++i) {
537 exprs[i] = sy->out[sy->out_count+i].out;
538 blocks[i] = sy->out[sy->out_count+i].block;
539 asvalue[i] = (ast_value*)exprs[i];
542 if (blocks[0] && !blocks[0]->exprs_count && op->id != opid1(',')) {
543 parseerror(parser, "internal error: operator cannot be applied on empty blocks");
547 #define NotSameType(T) \
548 (exprs[0]->expression.vtype != exprs[1]->expression.vtype || \
549 exprs[0]->expression.vtype != T)
550 #define CanConstFold1(A) \
551 (ast_istype((A), ast_value) && ((ast_value*)(A))->isconst)
552 #define CanConstFold(A, B) \
553 (CanConstFold1(A) && CanConstFold1(B))
554 #define ConstV(i) (asvalue[(i)]->constval.vvec)
555 #define ConstF(i) (asvalue[(i)]->constval.vfloat)
556 #define ConstS(i) (asvalue[(i)]->constval.vstring)
560 parseerror(parser, "internal error: unhandled operator: %s (%i)", op->op, (int)op->id);
564 if (exprs[0]->expression.vtype == TYPE_ENTITY) {
565 if (exprs[1]->expression.vtype != TYPE_FIELD) {
566 parseerror(parser, "type error: right hand of member-operand should be an entity-field");
569 out = (ast_expression*)ast_entfield_new(ctx, exprs[0], exprs[1]);
571 else if (exprs[0]->expression.vtype == TYPE_VECTOR) {
572 parseerror(parser, "internal error: vector access is not supposed to be handled at this point");
576 parseerror(parser, "type error: member-of operator on something that is not an entity or vector");
583 if (!ast_block_exprs_add(blocks[0], exprs[1]))
586 blocks[0] = ast_block_new(ctx);
587 if (!ast_block_exprs_add(blocks[0], exprs[0]) ||
588 !ast_block_exprs_add(blocks[0], exprs[1]))
593 if (!ast_block_set_type(blocks[0], exprs[1]))
596 sy->out[sy->out_count++] = syblock(ctx, blocks[0]);
600 switch (exprs[0]->expression.vtype) {
602 if (CanConstFold1(exprs[0]))
603 out = (ast_expression*)parser_const_float(parser, -ConstF(0));
605 out = (ast_expression*)ast_binary_new(ctx, INSTR_SUB_F,
606 (ast_expression*)parser_const_float_0(parser),
610 if (CanConstFold1(exprs[0]))
611 out = (ast_expression*)parser_const_vector_f(parser,
612 -ConstV(0).x, -ConstV(0).y, -ConstV(0).z);
614 out = (ast_expression*)ast_binary_new(ctx, INSTR_SUB_V,
615 (ast_expression*)parser_const_vector_0(parser),
619 parseerror(parser, "invalid types used in expression: cannot negate type %s",
620 type_name[exprs[0]->expression.vtype]);
626 switch (exprs[0]->expression.vtype) {
628 if (CanConstFold1(exprs[0]))
629 out = (ast_expression*)parser_const_float(parser, !ConstF(0));
631 out = (ast_expression*)ast_unary_new(ctx, INSTR_NOT_F, exprs[0]);
634 if (CanConstFold1(exprs[0]))
635 out = (ast_expression*)parser_const_float(parser,
636 (!ConstV(0).x && !ConstV(0).y && !ConstV(0).z));
638 out = (ast_expression*)ast_unary_new(ctx, INSTR_NOT_V, exprs[0]);
641 if (CanConstFold1(exprs[0]))
642 out = (ast_expression*)parser_const_float(parser, !ConstS(0) || !*ConstS(0));
644 out = (ast_expression*)ast_unary_new(ctx, INSTR_NOT_S, exprs[0]);
646 /* we don't constant-fold NOT for these types */
648 out = (ast_expression*)ast_unary_new(ctx, INSTR_NOT_ENT, exprs[0]);
651 out = (ast_expression*)ast_unary_new(ctx, INSTR_NOT_FNC, exprs[0]);
654 parseerror(parser, "invalid types used in expression: cannot logically negate type %s",
655 type_name[exprs[0]->expression.vtype]);
661 if (exprs[0]->expression.vtype != exprs[1]->expression.vtype ||
662 (exprs[0]->expression.vtype != TYPE_VECTOR && exprs[0]->expression.vtype != TYPE_FLOAT) )
664 parseerror(parser, "invalid types used in expression: cannot add type %s and %s",
665 type_name[exprs[0]->expression.vtype],
666 type_name[exprs[1]->expression.vtype]);
669 switch (exprs[0]->expression.vtype) {
671 if (CanConstFold(exprs[0], exprs[1]))
673 out = (ast_expression*)parser_const_float(parser, ConstF(0) + ConstF(1));
676 out = (ast_expression*)ast_binary_new(ctx, INSTR_ADD_F, exprs[0], exprs[1]);
679 if (CanConstFold(exprs[0], exprs[1]))
680 out = (ast_expression*)parser_const_vector(parser, vec3_add(ConstV(0), ConstV(1)));
682 out = (ast_expression*)ast_binary_new(ctx, INSTR_ADD_V, exprs[0], exprs[1]);
685 parseerror(parser, "invalid types used in expression: cannot add type %s and %s",
686 type_name[exprs[0]->expression.vtype],
687 type_name[exprs[1]->expression.vtype]);
692 if (exprs[0]->expression.vtype != exprs[1]->expression.vtype ||
693 (exprs[0]->expression.vtype != TYPE_VECTOR && exprs[0]->expression.vtype != TYPE_FLOAT) )
695 parseerror(parser, "invalid types used in expression: cannot subtract type %s from %s",
696 type_name[exprs[1]->expression.vtype],
697 type_name[exprs[0]->expression.vtype]);
700 switch (exprs[0]->expression.vtype) {
702 if (CanConstFold(exprs[0], exprs[1]))
703 out = (ast_expression*)parser_const_float(parser, ConstF(0) - ConstF(1));
705 out = (ast_expression*)ast_binary_new(ctx, INSTR_SUB_F, exprs[0], exprs[1]);
708 if (CanConstFold(exprs[0], exprs[1]))
709 out = (ast_expression*)parser_const_vector(parser, vec3_sub(ConstV(0), ConstV(1)));
711 out = (ast_expression*)ast_binary_new(ctx, INSTR_SUB_V, exprs[0], exprs[1]);
714 parseerror(parser, "invalid types used in expression: cannot subtract type %s from %s",
715 type_name[exprs[1]->expression.vtype],
716 type_name[exprs[0]->expression.vtype]);
721 if (exprs[0]->expression.vtype != exprs[1]->expression.vtype &&
722 exprs[0]->expression.vtype != TYPE_VECTOR &&
723 exprs[0]->expression.vtype != TYPE_FLOAT &&
724 exprs[1]->expression.vtype != TYPE_VECTOR &&
725 exprs[1]->expression.vtype != TYPE_FLOAT)
727 parseerror(parser, "invalid types used in expression: cannot multiply types %s and %s",
728 type_name[exprs[1]->expression.vtype],
729 type_name[exprs[0]->expression.vtype]);
732 switch (exprs[0]->expression.vtype) {
734 if (exprs[1]->expression.vtype == TYPE_VECTOR)
736 if (CanConstFold(exprs[0], exprs[1]))
737 out = (ast_expression*)parser_const_vector(parser, vec3_mulvf(ConstV(1), ConstF(0)));
739 out = (ast_expression*)ast_binary_new(ctx, INSTR_MUL_FV, exprs[0], exprs[1]);
743 if (CanConstFold(exprs[0], exprs[1]))
744 out = (ast_expression*)parser_const_float(parser, ConstF(0) * ConstF(1));
746 out = (ast_expression*)ast_binary_new(ctx, INSTR_MUL_F, exprs[0], exprs[1]);
750 if (exprs[1]->expression.vtype == TYPE_FLOAT)
752 if (CanConstFold(exprs[0], exprs[1]))
753 out = (ast_expression*)parser_const_vector(parser, vec3_mulvf(ConstV(0), ConstF(1)));
755 out = (ast_expression*)ast_binary_new(ctx, INSTR_MUL_VF, exprs[0], exprs[1]);
759 if (CanConstFold(exprs[0], exprs[1]))
760 out = (ast_expression*)parser_const_float(parser, vec3_mulvv(ConstV(0), ConstV(1)));
762 out = (ast_expression*)ast_binary_new(ctx, INSTR_MUL_V, exprs[0], exprs[1]);
766 parseerror(parser, "invalid types used in expression: cannot multiply types %s and %s",
767 type_name[exprs[1]->expression.vtype],
768 type_name[exprs[0]->expression.vtype]);
773 if (NotSameType(TYPE_FLOAT)) {
774 parseerror(parser, "invalid types used in expression: cannot divide types %s and %s",
775 type_name[exprs[0]->expression.vtype],
776 type_name[exprs[1]->expression.vtype]);
779 if (CanConstFold(exprs[0], exprs[1]))
780 out = (ast_expression*)parser_const_float(parser, ConstF(0) / ConstF(1));
782 out = (ast_expression*)ast_binary_new(ctx, INSTR_DIV_F, exprs[0], exprs[1]);
786 parseerror(parser, "qc does not have a modulo operator");
790 if (NotSameType(TYPE_FLOAT)) {
791 parseerror(parser, "invalid types used in expression: cannot perform bit operations between types %s and %s",
792 type_name[exprs[0]->expression.vtype],
793 type_name[exprs[1]->expression.vtype]);
796 if (CanConstFold(exprs[0], exprs[1]))
797 out = (ast_expression*)parser_const_float(parser,
798 (op->id == opid1('|') ? (float)( ((qcint)ConstF(0)) | ((qcint)ConstF(1)) ) :
799 (float)( ((qcint)ConstF(0)) & ((qcint)ConstF(1)) ) ));
801 out = (ast_expression*)ast_binary_new(ctx,
802 (op->id == opid1('|') ? INSTR_BITOR : INSTR_BITAND),
806 parseerror(parser, "TODO: bitxor");
811 case opid3('<','<','='):
812 case opid3('>','>','='):
813 parseerror(parser, "TODO: shifts");
817 generated_op += 1; /* INSTR_OR */
819 generated_op += INSTR_AND;
820 if (NotSameType(TYPE_FLOAT)) {
821 parseerror(parser, "invalid types used in expression: cannot perform logical operations between types %s and %s",
822 type_name[exprs[0]->expression.vtype],
823 type_name[exprs[1]->expression.vtype]);
824 parseerror(parser, "TODO: logical ops for arbitrary types using INSTR_NOT");
825 parseerror(parser, "TODO: optional early out");
828 if (opts_standard == COMPILER_GMQCC)
829 con_out("TODO: early out logic\n");
830 if (CanConstFold(exprs[0], exprs[1]))
831 out = (ast_expression*)parser_const_float(parser,
832 (generated_op == INSTR_OR ? (ConstF(0) || ConstF(1)) : (ConstF(0) && ConstF(1))));
834 out = (ast_expression*)ast_binary_new(ctx, generated_op, exprs[0], exprs[1]);
838 generated_op += 1; /* INSTR_GT */
840 generated_op += 1; /* INSTR_LT */
841 case opid2('>', '='):
842 generated_op += 1; /* INSTR_GE */
843 case opid2('<', '='):
844 generated_op += INSTR_LE;
845 if (NotSameType(TYPE_FLOAT)) {
846 parseerror(parser, "invalid types used in expression: cannot perform comparison between types %s and %s",
847 type_name[exprs[0]->expression.vtype],
848 type_name[exprs[1]->expression.vtype]);
851 out = (ast_expression*)ast_binary_new(ctx, generated_op, exprs[0], exprs[1]);
853 case opid2('!', '='):
854 if (exprs[0]->expression.vtype != exprs[1]->expression.vtype) {
855 parseerror(parser, "invalid types used in expression: cannot perform comparison between types %s and %s",
856 type_name[exprs[0]->expression.vtype],
857 type_name[exprs[1]->expression.vtype]);
860 out = (ast_expression*)ast_binary_new(ctx, type_ne_instr[exprs[0]->expression.vtype], exprs[0], exprs[1]);
862 case opid2('=', '='):
863 if (exprs[0]->expression.vtype != exprs[1]->expression.vtype) {
864 parseerror(parser, "invalid types used in expression: cannot perform comparison between types %s and %s",
865 type_name[exprs[0]->expression.vtype],
866 type_name[exprs[1]->expression.vtype]);
869 out = (ast_expression*)ast_binary_new(ctx, type_eq_instr[exprs[0]->expression.vtype], exprs[0], exprs[1]);
873 if (ast_istype(exprs[0], ast_entfield)) {
874 ast_expression *field = ((ast_entfield*)exprs[0])->field;
875 assignop = type_storep_instr[exprs[0]->expression.vtype];
876 if (!ast_compare_type(field->expression.next, exprs[1])) {
879 ast_type_to_string(field->expression.next, ty1, sizeof(ty1));
880 ast_type_to_string(exprs[1], ty2, sizeof(ty2));
881 if (opts_standard == COMPILER_QCC &&
882 field->expression.next->expression.vtype == TYPE_FUNCTION &&
883 exprs[1]->expression.vtype == TYPE_FUNCTION)
885 if (parsewarning(parser, WARN_ASSIGN_FUNCTION_TYPES,
886 "invalid types in assignment: cannot assign %s to %s", ty2, ty1))
892 parseerror(parser, "invalid types in assignment: cannot assign %s to %s", ty2, ty1);
897 assignop = type_store_instr[exprs[0]->expression.vtype];
898 if (!ast_compare_type(exprs[0], exprs[1])) {
901 ast_type_to_string(exprs[0], ty1, sizeof(ty1));
902 ast_type_to_string(exprs[1], ty2, sizeof(ty2));
903 if (opts_standard == COMPILER_QCC &&
904 exprs[0]->expression.vtype == TYPE_FUNCTION &&
905 exprs[1]->expression.vtype == TYPE_FUNCTION)
907 if (parsewarning(parser, WARN_ASSIGN_FUNCTION_TYPES,
908 "invalid types in assignment: cannot assign %s to %s", ty2, ty1))
914 parseerror(parser, "invalid types in assignment: cannot assign %s to %s", ty2, ty1);
917 out = (ast_expression*)ast_store_new(ctx, assignop, exprs[0], exprs[1]);
921 if (exprs[0]->expression.vtype != exprs[1]->expression.vtype ||
922 (exprs[0]->expression.vtype != TYPE_VECTOR && exprs[0]->expression.vtype != TYPE_FLOAT) )
924 parseerror(parser, "invalid types used in expression: cannot add or subtract type %s and %s",
925 type_name[exprs[0]->expression.vtype],
926 type_name[exprs[1]->expression.vtype]);
929 if (ast_istype(exprs[0], ast_entfield))
930 assignop = type_storep_instr[exprs[0]->expression.vtype];
932 assignop = type_store_instr[exprs[0]->expression.vtype];
933 switch (exprs[0]->expression.vtype) {
935 out = (ast_expression*)ast_binstore_new(ctx, assignop,
936 (op->id == opid2('+','=') ? INSTR_ADD_F : INSTR_SUB_F),
940 out = (ast_expression*)ast_binstore_new(ctx, assignop,
941 (op->id == opid2('+','=') ? INSTR_ADD_V : INSTR_SUB_V),
945 parseerror(parser, "invalid types used in expression: cannot add or subtract type %s and %s",
946 type_name[exprs[0]->expression.vtype],
947 type_name[exprs[1]->expression.vtype]);
955 parseerror(parser, "failed to apply operand %s", op->op);
959 DEBUGSHUNTDO(con_out("applied %s\n", op->op));
960 sy->out[sy->out_count++] = syexp(ctx, out);
964 static bool parser_close_call(parser_t *parser, shunt *sy)
966 /* was a function call */
974 fid = sy->ops[sy->ops_count].off;
976 /* out[fid] is the function
977 * everything above is parameters...
979 * 1 params = ast_expression
983 if (sy->out_count < 1 || sy->out_count <= fid) {
984 parseerror(parser, "internal error: function call needs function and parameter list...");
988 fun = sy->out[fid].out;
990 call = ast_call_new(sy->ops[sy->ops_count].ctx, fun);
992 parseerror(parser, "out of memory");
996 if (fid+1 == sy->out_count) {
999 } else if (fid+2 == sy->out_count) {
1002 params = sy->out[sy->out_count].block;
1006 if (!ast_call_params_add(call, sy->out[sy->out_count].out)) {
1007 ast_delete(sy->out[sy->out_count].out);
1008 parseerror(parser, "out of memory");
1012 paramcount = params->exprs_count;
1013 MEM_VECTOR_MOVE(params, exprs, call, params);
1016 if (!ast_call_check_types(call))
1019 parseerror(parser, "invalid function call");
1023 /* overwrite fid, the function, with a call */
1024 sy->out[fid] = syexp(call->expression.node.context, (ast_expression*)call);
1026 if (fun->expression.vtype != TYPE_FUNCTION) {
1027 parseerror(parser, "not a function (%s)", type_name[fun->expression.vtype]);
1031 if (!fun->expression.next) {
1032 parseerror(parser, "could not determine function return type");
1035 if (fun->expression.params_count != paramcount &&
1036 !(fun->expression.variadic &&
1037 fun->expression.params_count < paramcount))
1040 const char *fewmany = (fun->expression.params_count > paramcount) ? "few" : "many";
1042 fval = (ast_istype(fun, ast_value) ? ((ast_value*)fun) : NULL);
1043 if (opts_standard == COMPILER_GMQCC)
1046 parseerror(parser, "too %s parameters for call to %s: expected %i, got %i\n"
1047 " -> `%s` has been declared here: %s:%i",
1048 fewmany, fval->name, (int)fun->expression.params_count, (int)paramcount,
1049 fval->name, ast_ctx(fun).file, (int)ast_ctx(fun).line);
1051 parseerror(parser, "too %s parameters for function call: expected %i, got %i\n"
1052 " -> `%s` has been declared here: %s:%i",
1053 fewmany, fval->name, (int)fun->expression.params_count, (int)paramcount,
1054 fval->name, ast_ctx(fun).file, (int)ast_ctx(fun).line);
1060 return !parsewarning(parser, WARN_TOO_FEW_PARAMETERS,
1061 "too %s parameters for call to %s: expected %i, got %i\n"
1062 " -> `%s` has been declared here: %s:%i",
1063 fewmany, fval->name, (int)fun->expression.params_count, (int)paramcount,
1064 fval->name, ast_ctx(fun).file, (int)ast_ctx(fun).line);
1066 return !parsewarning(parser, WARN_TOO_FEW_PARAMETERS,
1067 "too %s parameters for function call: expected %i, got %i\n"
1068 " -> `%s` has been declared here: %s:%i",
1069 fewmany, fval->name, (int)fun->expression.params_count, (int)paramcount,
1070 fval->name, ast_ctx(fun).file, (int)ast_ctx(fun).line);
1078 static bool parser_close_paren(parser_t *parser, shunt *sy, bool functions_only)
1080 if (!sy->ops_count) {
1081 parseerror(parser, "unmatched closing paren");
1084 /* this would for bit a + (x) because there are no operators inside (x)
1085 if (sy->ops[sy->ops_count-1].paren == 1) {
1086 parseerror(parser, "empty parenthesis expression");
1090 while (sy->ops_count) {
1091 if (sy->ops[sy->ops_count-1].paren == 'f') {
1092 if (!parser_close_call(parser, sy))
1096 if (sy->ops[sy->ops_count-1].paren == 1) {
1098 return !functions_only;
1100 if (!parser_sy_pop(parser, sy))
1106 static void parser_reclassify_token(parser_t *parser)
1109 for (i = 0; i < operator_count; ++i) {
1110 if (!strcmp(parser_tokval(parser), operators[i].op)) {
1111 parser->tok = TOKEN_OPERATOR;
1117 static ast_expression* parse_expression_leave(parser_t *parser, bool stopatcomma)
1119 ast_expression *expr = NULL;
1121 bool wantop = false;
1122 bool gotmemberof = false;
1124 /* count the parens because an if starts with one, so the
1125 * end of a condition is an unmatched closing paren
1129 MEM_VECTOR_INIT(&sy, out);
1130 MEM_VECTOR_INIT(&sy, ops);
1132 parser->lex->flags.noops = false;
1134 parser_reclassify_token(parser);
1139 gotmemberof = false;
1141 parser->memberof = 0;
1143 if (parser->tok == TOKEN_IDENT)
1145 ast_expression *var;
1147 parseerror(parser, "expected operator or end of statement");
1152 if (opts_standard == COMPILER_GMQCC)
1154 if (parser->memberof == TYPE_ENTITY) {
1155 /* still get vars first since there could be a fieldpointer */
1156 var = parser_find_var(parser, parser_tokval(parser));
1158 var = parser_find_field(parser, parser_tokval(parser));
1160 else if (parser->memberof == TYPE_VECTOR)
1162 parseerror(parser, "TODO: implement effective vector member access");
1165 else if (parser->memberof) {
1166 parseerror(parser, "namespace for member not found");
1170 var = parser_find_var(parser, parser_tokval(parser));
1172 var = parser_find_var(parser, parser_tokval(parser));
1174 var = parser_find_field(parser, parser_tokval(parser));
1177 parseerror(parser, "unexpected ident: %s", parser_tokval(parser));
1180 if (ast_istype(var, ast_value))
1181 ((ast_value*)var)->uses++;
1182 if (!shunt_out_add(&sy, syexp(parser_ctx(parser), var))) {
1183 parseerror(parser, "out of memory");
1186 DEBUGSHUNTDO(con_out("push %s\n", parser_tokval(parser)));
1188 else if (parser->tok == TOKEN_FLOATCONST) {
1191 parseerror(parser, "expected operator or end of statement, got constant");
1195 val = parser_const_float(parser, (parser_token(parser)->constval.f));
1198 if (!shunt_out_add(&sy, syexp(parser_ctx(parser), (ast_expression*)val))) {
1199 parseerror(parser, "out of memory");
1202 DEBUGSHUNTDO(con_out("push %g\n", parser_token(parser)->constval.f));
1204 else if (parser->tok == TOKEN_INTCONST) {
1207 parseerror(parser, "expected operator or end of statement, got constant");
1211 val = parser_const_float(parser, (double)(parser_token(parser)->constval.i));
1214 if (!shunt_out_add(&sy, syexp(parser_ctx(parser), (ast_expression*)val))) {
1215 parseerror(parser, "out of memory");
1218 DEBUGSHUNTDO(con_out("push %i\n", parser_token(parser)->constval.i));
1220 else if (parser->tok == TOKEN_STRINGCONST) {
1223 parseerror(parser, "expected operator or end of statement, got constant");
1227 val = parser_const_string(parser, parser_tokval(parser));
1230 if (!shunt_out_add(&sy, syexp(parser_ctx(parser), (ast_expression*)val))) {
1231 parseerror(parser, "out of memory");
1234 DEBUGSHUNTDO(con_out("push string\n"));
1236 else if (parser->tok == TOKEN_VECTORCONST) {
1239 parseerror(parser, "expected operator or end of statement, got constant");
1243 val = parser_const_vector(parser, parser_token(parser)->constval.v);
1246 if (!shunt_out_add(&sy, syexp(parser_ctx(parser), (ast_expression*)val))) {
1247 parseerror(parser, "out of memory");
1250 DEBUGSHUNTDO(con_out("push '%g %g %g'\n",
1251 parser_token(parser)->constval.v.x,
1252 parser_token(parser)->constval.v.y,
1253 parser_token(parser)->constval.v.z));
1255 else if (parser->tok == '(') {
1256 parseerror(parser, "internal error: '(' should be classified as operator");
1259 else if (parser->tok == ')') {
1261 DEBUGSHUNTDO(con_out("do[op] )\n"));
1265 /* we do expect an operator next */
1266 /* closing an opening paren */
1267 if (!parser_close_paren(parser, &sy, false))
1270 DEBUGSHUNTDO(con_out("do[nop] )\n"));
1274 /* allowed for function calls */
1275 if (!parser_close_paren(parser, &sy, true))
1280 else if (parser->tok != TOKEN_OPERATOR) {
1282 parseerror(parser, "expected operator or end of statement");
1289 /* classify the operator */
1290 /* TODO: suffix operators */
1291 const oper_info *op;
1292 const oper_info *olast = NULL;
1294 for (o = 0; o < operator_count; ++o) {
1295 if ((!(operators[o].flags & OP_PREFIX) == wantop) &&
1296 !(operators[o].flags & OP_SUFFIX) && /* remove this */
1297 !strcmp(parser_tokval(parser), operators[o].op))
1302 if (o == operator_count) {
1303 /* no operator found... must be the end of the statement */
1306 /* found an operator */
1309 /* when declaring variables, a comma starts a new variable */
1310 if (op->id == opid1(',') && !parens && stopatcomma) {
1311 /* fixup the token */
1316 if (sy.ops_count && !sy.ops[sy.ops_count-1].paren)
1317 olast = &operators[sy.ops[sy.ops_count-1].etype-1];
1320 (op->prec < olast->prec) ||
1321 (op->assoc == ASSOC_LEFT && op->prec <= olast->prec) ) )
1323 if (!parser_sy_pop(parser, &sy))
1325 if (sy.ops_count && !sy.ops[sy.ops_count-1].paren)
1326 olast = &operators[sy.ops[sy.ops_count-1].etype-1];
1331 if (op->id == opid1('.') && opts_standard == COMPILER_GMQCC) {
1332 /* for gmqcc standard: open up the namespace of the previous type */
1333 ast_expression *prevex = sy.out[sy.out_count-1].out;
1335 parseerror(parser, "unexpected member operator");
1338 if (prevex->expression.vtype == TYPE_ENTITY)
1339 parser->memberof = TYPE_ENTITY;
1340 else if (prevex->expression.vtype == TYPE_VECTOR)
1341 parser->memberof = TYPE_VECTOR;
1343 parseerror(parser, "type error: type has no members");
1349 if (op->id == opid1('(')) {
1351 DEBUGSHUNTDO(con_out("push [op] (\n"));
1353 /* we expected an operator, this is the function-call operator */
1354 if (!shunt_ops_add(&sy, syparen(parser_ctx(parser), 'f', sy.out_count-1))) {
1355 parseerror(parser, "out of memory");
1360 if (!shunt_ops_add(&sy, syparen(parser_ctx(parser), 1, 0))) {
1361 parseerror(parser, "out of memory");
1364 DEBUGSHUNTDO(con_out("push [nop] (\n"));
1368 DEBUGSHUNTDO(con_out("push operator %s\n", op->op));
1369 if (!shunt_ops_add(&sy, syop(parser_ctx(parser), op)))
1374 if (!parser_next(parser)) {
1377 if (parser->tok == ';' || parser->tok == ']') {
1382 while (sy.ops_count) {
1383 if (!parser_sy_pop(parser, &sy))
1387 parser->lex->flags.noops = true;
1388 if (!sy.out_count) {
1389 parseerror(parser, "empty expression");
1392 expr = sy.out[0].out;
1393 MEM_VECTOR_CLEAR(&sy, out);
1394 MEM_VECTOR_CLEAR(&sy, ops);
1395 DEBUGSHUNTDO(con_out("shunt done\n"));
1399 parser->lex->flags.noops = true;
1400 MEM_VECTOR_CLEAR(&sy, out);
1401 MEM_VECTOR_CLEAR(&sy, ops);
1405 static ast_expression* parse_expression(parser_t *parser, bool stopatcomma)
1407 ast_expression *e = parse_expression_leave(parser, stopatcomma);
1410 if (!parser_next(parser)) {
1417 static bool parse_if(parser_t *parser, ast_block *block, ast_expression **out)
1420 ast_expression *cond, *ontrue, *onfalse = NULL;
1423 lex_ctx ctx = parser_ctx(parser);
1425 /* skip the 'if', parse an optional 'not' and check for an opening paren */
1426 if (!parser_next(parser)) {
1427 parseerror(parser, "expected condition or 'not'");
1430 if (parser->tok == TOKEN_KEYWORD && !strcmp(parser_tokval(parser), "not")) {
1432 if (!parser_next(parser)) {
1433 parseerror(parser, "expected condition in parenthesis");
1437 if (parser->tok != '(') {
1438 parseerror(parser, "expected 'if' condition in parenthesis");
1441 /* parse into the expression */
1442 if (!parser_next(parser)) {
1443 parseerror(parser, "expected 'if' condition after opening paren");
1446 /* parse the condition */
1447 cond = parse_expression_leave(parser, false);
1451 if (parser->tok != ')') {
1452 parseerror(parser, "expected closing paren after 'if' condition");
1456 /* parse into the 'then' branch */
1457 if (!parser_next(parser)) {
1458 parseerror(parser, "expected statement for on-true branch of 'if'");
1462 ontrue = parse_statement_or_block(parser);
1467 /* check for an else */
1468 if (!strcmp(parser_tokval(parser), "else")) {
1469 /* parse into the 'else' branch */
1470 if (!parser_next(parser)) {
1471 parseerror(parser, "expected on-false branch after 'else'");
1476 onfalse = parse_statement_or_block(parser);
1485 ifthen = ast_ifthen_new(ctx, cond, onfalse, ontrue);
1487 ifthen = ast_ifthen_new(ctx, cond, ontrue, onfalse);
1488 *out = (ast_expression*)ifthen;
1492 static bool parse_while(parser_t *parser, ast_block *block, ast_expression **out)
1495 ast_expression *cond, *ontrue;
1497 lex_ctx ctx = parser_ctx(parser);
1499 /* skip the 'while' and check for opening paren */
1500 if (!parser_next(parser) || parser->tok != '(') {
1501 parseerror(parser, "expected 'while' condition in parenthesis");
1504 /* parse into the expression */
1505 if (!parser_next(parser)) {
1506 parseerror(parser, "expected 'while' condition after opening paren");
1509 /* parse the condition */
1510 cond = parse_expression_leave(parser, false);
1514 if (parser->tok != ')') {
1515 parseerror(parser, "expected closing paren after 'while' condition");
1519 /* parse into the 'then' branch */
1520 if (!parser_next(parser)) {
1521 parseerror(parser, "expected while-loop body");
1525 ontrue = parse_statement_or_block(parser);
1531 aloop = ast_loop_new(ctx, NULL, cond, NULL, NULL, ontrue);
1532 *out = (ast_expression*)aloop;
1536 static bool parse_dowhile(parser_t *parser, ast_block *block, ast_expression **out)
1539 ast_expression *cond, *ontrue;
1541 lex_ctx ctx = parser_ctx(parser);
1543 /* skip the 'do' and get the body */
1544 if (!parser_next(parser)) {
1545 parseerror(parser, "expected loop body");
1548 ontrue = parse_statement_or_block(parser);
1552 /* expect the "while" */
1553 if (parser->tok != TOKEN_KEYWORD ||
1554 strcmp(parser_tokval(parser), "while"))
1556 parseerror(parser, "expected 'while' and condition");
1561 /* skip the 'while' and check for opening paren */
1562 if (!parser_next(parser) || parser->tok != '(') {
1563 parseerror(parser, "expected 'while' condition in parenthesis");
1567 /* parse into the expression */
1568 if (!parser_next(parser)) {
1569 parseerror(parser, "expected 'while' condition after opening paren");
1573 /* parse the condition */
1574 cond = parse_expression_leave(parser, false);
1578 if (parser->tok != ')') {
1579 parseerror(parser, "expected closing paren after 'while' condition");
1585 if (!parser_next(parser) || parser->tok != ';') {
1586 parseerror(parser, "expected semicolon after condition");
1592 if (!parser_next(parser)) {
1593 parseerror(parser, "parse error");
1599 aloop = ast_loop_new(ctx, NULL, NULL, cond, NULL, ontrue);
1600 *out = (ast_expression*)aloop;
1604 static bool parse_for(parser_t *parser, ast_block *block, ast_expression **out)
1607 ast_expression *initexpr, *cond, *increment, *ontrue;
1608 size_t oldblocklocal;
1611 lex_ctx ctx = parser_ctx(parser);
1613 oldblocklocal = parser->blocklocal;
1614 parser->blocklocal = parser->locals_count;
1621 /* skip the 'while' and check for opening paren */
1622 if (!parser_next(parser) || parser->tok != '(') {
1623 parseerror(parser, "expected 'for' expressions in parenthesis");
1626 /* parse into the expression */
1627 if (!parser_next(parser)) {
1628 parseerror(parser, "expected 'for' initializer after opening paren");
1632 if (parser->tok == TOKEN_TYPENAME) {
1633 if (opts_standard != COMPILER_GMQCC) {
1634 if (parsewarning(parser, WARN_EXTENSIONS,
1635 "current standard does not allow variable declarations in for-loop initializers"))
1639 parseerror(parser, "TODO: assignment of new variables to be non-const");
1641 if (!parse_variable(parser, block))
1644 else if (parser->tok != ';')
1646 initexpr = parse_expression_leave(parser, false);
1651 /* move on to condition */
1652 if (parser->tok != ';') {
1653 parseerror(parser, "expected semicolon after for-loop initializer");
1656 if (!parser_next(parser)) {
1657 parseerror(parser, "expected for-loop condition");
1661 /* parse the condition */
1662 if (parser->tok != ';') {
1663 cond = parse_expression_leave(parser, false);
1668 /* move on to incrementor */
1669 if (parser->tok != ';') {
1670 parseerror(parser, "expected semicolon after for-loop initializer");
1673 if (!parser_next(parser)) {
1674 parseerror(parser, "expected for-loop condition");
1678 /* parse the incrementor */
1679 if (parser->tok != ')') {
1680 increment = parse_expression_leave(parser, false);
1683 if (!ast_istype(increment, ast_store) &&
1684 !ast_istype(increment, ast_call) &&
1685 !ast_istype(increment, ast_binstore))
1687 if (genwarning(ast_ctx(increment), WARN_EFFECTLESS_STATEMENT, "statement has no effect"))
1693 if (parser->tok != ')') {
1694 parseerror(parser, "expected closing paren after 'for-loop' incrementor");
1697 /* parse into the 'then' branch */
1698 if (!parser_next(parser)) {
1699 parseerror(parser, "expected for-loop body");
1702 ontrue = parse_statement_or_block(parser);
1707 aloop = ast_loop_new(ctx, initexpr, cond, NULL, increment, ontrue);
1708 *out = (ast_expression*)aloop;
1710 while (parser->locals_count > parser->blocklocal)
1711 retval = retval && parser_pop_local(parser);
1712 parser->blocklocal = oldblocklocal;
1715 if (initexpr) ast_delete(initexpr);
1716 if (cond) ast_delete(cond);
1717 if (increment) ast_delete(increment);
1718 while (parser->locals_count > parser->blocklocal)
1719 (void)!parser_pop_local(parser);
1720 parser->blocklocal = oldblocklocal;
1724 static bool parse_statement(parser_t *parser, ast_block *block, ast_expression **out)
1726 if (parser->tok == TOKEN_TYPENAME)
1728 /* local variable */
1730 parseerror(parser, "cannot declare a variable from here");
1733 if (opts_standard == COMPILER_QCC) {
1734 if (parsewarning(parser, WARN_EXTENSIONS, "missing 'local' keyword when declaring a local variable"))
1737 if (!parse_variable(parser, block))
1742 else if (parser->tok == TOKEN_KEYWORD)
1744 if (!strcmp(parser_tokval(parser), "local"))
1747 parseerror(parser, "cannot declare a local variable here");
1750 if (!parser_next(parser)) {
1751 parseerror(parser, "expected variable declaration");
1754 if (!parse_variable(parser, block))
1759 else if (!strcmp(parser_tokval(parser), "return"))
1761 ast_expression *exp = NULL;
1762 ast_return *ret = NULL;
1763 ast_value *expected = parser->function->vtype;
1765 if (!parser_next(parser)) {
1766 parseerror(parser, "expected return expression");
1770 if (parser->tok != ';') {
1771 exp = parse_expression(parser, false);
1775 if (exp->expression.vtype != expected->expression.next->expression.vtype) {
1776 parseerror(parser, "return with invalid expression");
1779 ret = ast_return_new(exp->expression.node.context, exp);
1785 if (!parser_next(parser))
1786 parseerror(parser, "parse error");
1787 if (expected->expression.next->expression.vtype != TYPE_VOID) {
1788 if (opts_standard != COMPILER_GMQCC)
1789 (void)!parsewarning(parser, WARN_MISSING_RETURN_VALUES, "return without value");
1791 parseerror(parser, "return without value");
1793 ret = ast_return_new(parser_ctx(parser), NULL);
1795 *out = (ast_expression*)ret;
1798 else if (!strcmp(parser_tokval(parser), "if"))
1800 return parse_if(parser, block, out);
1802 else if (!strcmp(parser_tokval(parser), "while"))
1804 return parse_while(parser, block, out);
1806 else if (!strcmp(parser_tokval(parser), "do"))
1808 return parse_dowhile(parser, block, out);
1810 else if (!strcmp(parser_tokval(parser), "for"))
1812 if (opts_standard == COMPILER_QCC) {
1813 if (parsewarning(parser, WARN_EXTENSIONS, "for loops are not recognized in the original Quake C standard, to enable try an alternate standard --std=?"))
1816 return parse_for(parser, block, out);
1818 parseerror(parser, "Unexpected keyword");
1821 else if (parser->tok == '{')
1824 inner = parse_block(parser, false);
1827 *out = (ast_expression*)inner;
1832 ast_expression *exp = parse_expression(parser, false);
1836 if (!ast_istype(exp, ast_store) &&
1837 !ast_istype(exp, ast_call) &&
1838 !ast_istype(exp, ast_binstore))
1840 if (genwarning(ast_ctx(exp), WARN_EFFECTLESS_STATEMENT, "statement has no effect"))
1847 static bool GMQCC_WARN parser_pop_local(parser_t *parser)
1850 parser->locals_count--;
1852 ve = &parser->locals[parser->locals_count];
1853 if (ast_istype(ve->var, ast_value) && !(((ast_value*)(ve->var))->uses)) {
1854 if (parsewarning(parser, WARN_UNUSED_VARIABLE, "unused variable: `%s`", ve->name))
1857 mem_d(parser->locals[parser->locals_count].name);
1861 static bool parse_block_into(parser_t *parser, ast_block *block, bool warnreturn)
1863 size_t oldblocklocal;
1866 oldblocklocal = parser->blocklocal;
1867 parser->blocklocal = parser->locals_count;
1869 if (!parser_next(parser)) { /* skip the '{' */
1870 parseerror(parser, "expected function body");
1874 while (parser->tok != TOKEN_EOF && parser->tok < TOKEN_ERROR)
1876 ast_expression *expr;
1877 if (parser->tok == '}')
1880 if (!parse_statement(parser, block, &expr)) {
1881 /* parseerror(parser, "parse error"); */
1887 if (!ast_block_exprs_add(block, expr)) {
1894 if (parser->tok != '}') {
1897 if (warnreturn && parser->function->vtype->expression.next->expression.vtype != TYPE_VOID)
1899 if (!block->exprs_count ||
1900 !ast_istype(block->exprs[block->exprs_count-1], ast_return))
1902 if (parsewarning(parser, WARN_MISSING_RETURN_VALUES, "control reaches end of non-void function")) {
1908 (void)parser_next(parser);
1912 while (parser->locals_count > parser->blocklocal)
1913 retval = retval && parser_pop_local(parser);
1914 parser->blocklocal = oldblocklocal;
1918 static ast_block* parse_block(parser_t *parser, bool warnreturn)
1921 block = ast_block_new(parser_ctx(parser));
1924 if (!parse_block_into(parser, block, warnreturn)) {
1925 ast_block_delete(block);
1931 static ast_expression* parse_statement_or_block(parser_t *parser)
1933 ast_expression *expr = NULL;
1934 if (parser->tok == '{')
1935 return (ast_expression*)parse_block(parser, false);
1936 if (!parse_statement(parser, NULL, &expr))
1942 static bool create_vector_members(parser_t *parser, ast_value *var, varentry_t *ve)
1945 size_t len = strlen(var->name);
1947 for (i = 0; i < 3; ++i) {
1948 ve[i].var = (ast_expression*)ast_member_new(ast_ctx(var), (ast_expression*)var, i);
1952 ve[i].name = (char*)mem_a(len+3);
1954 ast_delete(ve[i].var);
1958 memcpy(ve[i].name, var->name, len);
1959 ve[i].name[len] = '_';
1960 ve[i].name[len+1] = 'x'+i;
1961 ve[i].name[len+2] = 0;
1970 ast_delete(ve[i].var);
1977 static bool parse_function_body(parser_t *parser, ast_value *var)
1979 ast_block *block = NULL;
1984 ast_expression *framenum = NULL;
1985 ast_expression *nextthink = NULL;
1986 /* None of the following have to be deleted */
1987 ast_expression *fld_think = NULL, *fld_nextthink = NULL, *fld_frame = NULL;
1988 ast_expression *gbl_time = NULL, *gbl_self = NULL;
1989 bool has_frame_think;
1993 has_frame_think = false;
1994 old = parser->function;
1996 if (var->expression.variadic) {
1997 if (parsewarning(parser, WARN_VARIADIC_FUNCTION,
1998 "variadic function with implementation will not be able to access additional parameters"))
2004 if (parser->tok == '[') {
2005 /* got a frame definition: [ framenum, nextthink ]
2006 * this translates to:
2007 * self.frame = framenum;
2008 * self.nextthink = time + 0.1;
2009 * self.think = nextthink;
2013 fld_think = parser_find_field(parser, "think");
2014 fld_nextthink = parser_find_field(parser, "nextthink");
2015 fld_frame = parser_find_field(parser, "frame");
2016 if (!fld_think || !fld_nextthink || !fld_frame) {
2017 parseerror(parser, "cannot use [frame,think] notation without the required fields");
2018 parseerror(parser, "please declare the following entityfields: `frame`, `think`, `nextthink`");
2021 gbl_time = parser_find_global(parser, "time");
2022 gbl_self = parser_find_global(parser, "self");
2023 if (!gbl_time || !gbl_self) {
2024 parseerror(parser, "cannot use [frame,think] notation without the required globals");
2025 parseerror(parser, "please declare the following globals: `time`, `self`");
2029 if (!parser_next(parser))
2032 framenum = parse_expression_leave(parser, true);
2034 parseerror(parser, "expected a framenumber constant in[frame,think] notation");
2037 if (!ast_istype(framenum, ast_value) || !( (ast_value*)framenum )->isconst) {
2038 ast_unref(framenum);
2039 parseerror(parser, "framenumber in [frame,think] notation must be a constant");
2043 if (parser->tok != ',') {
2044 ast_unref(framenum);
2045 parseerror(parser, "expected comma after frame number in [frame,think] notation");
2046 parseerror(parser, "Got a %i\n", parser->tok);
2050 if (!parser_next(parser)) {
2051 ast_unref(framenum);
2055 if (parser->tok == TOKEN_IDENT && !parser_find_var(parser, parser_tokval(parser)))
2057 /* qc allows the use of not-yet-declared functions here
2058 * - this automatically creates a prototype */
2060 ast_value *thinkfunc;
2061 ast_expression *functype = fld_think->expression.next;
2063 thinkfunc = ast_value_new(parser_ctx(parser), parser_tokval(parser), functype->expression.vtype);
2064 if (!thinkfunc || !ast_type_adopt(thinkfunc, functype)) {
2065 ast_unref(framenum);
2066 parseerror(parser, "failed to create implicit prototype for `%s`", parser_tokval(parser));
2070 if (!parser_next(parser)) {
2071 ast_unref(framenum);
2072 ast_delete(thinkfunc);
2076 varent.var = (ast_expression*)thinkfunc;
2077 varent.name = util_strdup(thinkfunc->name);
2078 if (!parser_t_globals_add(parser, varent)) {
2079 ast_unref(framenum);
2080 ast_delete(thinkfunc);
2083 nextthink = (ast_expression*)thinkfunc;
2086 nextthink = parse_expression_leave(parser, true);
2088 ast_unref(framenum);
2089 parseerror(parser, "expected a think-function in [frame,think] notation");
2094 if (!ast_istype(nextthink, ast_value)) {
2095 parseerror(parser, "think-function in [frame,think] notation must be a constant");
2099 if (retval && parser->tok != ']') {
2100 parseerror(parser, "expected closing `]` for [frame,think] notation");
2104 if (retval && !parser_next(parser)) {
2108 if (retval && parser->tok != '{') {
2109 parseerror(parser, "a function body has to be declared after a [frame,think] declaration");
2114 ast_unref(nextthink);
2115 ast_unref(framenum);
2119 has_frame_think = true;
2122 block = ast_block_new(parser_ctx(parser));
2124 parseerror(parser, "failed to allocate block");
2125 if (has_frame_think) {
2126 ast_unref(nextthink);
2127 ast_unref(framenum);
2132 if (has_frame_think) {
2134 ast_expression *self_frame;
2135 ast_expression *self_nextthink;
2136 ast_expression *self_think;
2137 ast_expression *time_plus_1;
2138 ast_store *store_frame;
2139 ast_store *store_nextthink;
2140 ast_store *store_think;
2142 ctx = parser_ctx(parser);
2143 self_frame = (ast_expression*)ast_entfield_new(ctx, gbl_self, fld_frame);
2144 self_nextthink = (ast_expression*)ast_entfield_new(ctx, gbl_self, fld_nextthink);
2145 self_think = (ast_expression*)ast_entfield_new(ctx, gbl_self, fld_think);
2147 time_plus_1 = (ast_expression*)ast_binary_new(ctx, INSTR_ADD_F,
2148 gbl_time, (ast_expression*)parser_const_float(parser, 0.1));
2150 if (!self_frame || !self_nextthink || !self_think || !time_plus_1) {
2151 if (self_frame) ast_delete(self_frame);
2152 if (self_nextthink) ast_delete(self_nextthink);
2153 if (self_think) ast_delete(self_think);
2154 if (time_plus_1) ast_delete(time_plus_1);
2160 store_frame = ast_store_new(ctx, INSTR_STOREP_F, self_frame, framenum);
2161 store_nextthink = ast_store_new(ctx, INSTR_STOREP_F, self_nextthink, time_plus_1);
2162 store_think = ast_store_new(ctx, INSTR_STOREP_FNC, self_think, nextthink);
2165 ast_delete(self_frame);
2168 if (!store_nextthink) {
2169 ast_delete(self_nextthink);
2173 ast_delete(self_think);
2177 if (store_frame) ast_delete(store_frame);
2178 if (store_nextthink) ast_delete(store_nextthink);
2179 if (store_think) ast_delete(store_think);
2182 if (retval && !ast_block_exprs_add(block, (ast_expression*)store_frame)) {
2183 ast_delete(store_frame);
2184 ast_delete(store_nextthink);
2185 ast_delete(store_think);
2189 if (retval && !ast_block_exprs_add(block, (ast_expression*)store_nextthink)) {
2190 ast_delete(store_nextthink);
2191 ast_delete(store_think);
2195 if (retval && !ast_block_exprs_add(block, (ast_expression*)store_think) )
2197 ast_delete(store_think);
2203 parseerror(parser, "failed to generate code for [frame,think]");
2204 ast_unref(nextthink);
2205 ast_unref(framenum);
2211 for (parami = 0; parami < var->expression.params_count; ++parami) {
2214 ast_value *param = var->expression.params[parami];
2216 if (param->expression.vtype != TYPE_VECTOR &&
2217 (param->expression.vtype != TYPE_FIELD ||
2218 param->expression.next->expression.vtype != TYPE_VECTOR))
2223 if (!create_vector_members(parser, param, ve)) {
2224 ast_block_delete(block);
2228 for (e = 0; e < 3; ++e) {
2229 if (!parser_t_locals_add(parser, ve[e]))
2231 if (!ast_block_collect(block, ve[e].var)) {
2232 parser->locals_count--;
2235 ve[e].var = NULL; /* collected */
2238 parser->locals -= e;
2243 ast_block_delete(block);
2248 func = ast_function_new(ast_ctx(var), var->name, var);
2250 parseerror(parser, "failed to allocate function for `%s`", var->name);
2251 ast_block_delete(block);
2254 if (!parser_t_functions_add(parser, func)) {
2255 parseerror(parser, "failed to allocate slot for function `%s`", var->name);
2256 ast_block_delete(block);
2260 parser->function = func;
2261 if (!parse_block_into(parser, block, true)) {
2262 ast_block_delete(block);
2266 if (!ast_function_blocks_add(func, block)) {
2267 ast_block_delete(block);
2271 parser->function = old;
2272 while (parser->locals_count)
2273 retval = retval && parser_pop_local(parser);
2275 if (parser->tok == ';')
2276 return parser_next(parser);
2277 else if (opts_standard == COMPILER_QCC)
2278 parseerror(parser, "missing semicolon after function body (mandatory with -std=qcc)");
2282 parser->functions_count--;
2284 ast_function_delete(func);
2285 var->constval.vfunc = NULL;
2288 while (parser->locals_count) {
2289 parser->locals_count--;
2290 mem_d(parser->locals[parser->locals_count].name);
2292 parser->function = old;
2296 static bool parse_variable(parser_t *parser, ast_block *localblock)
2298 bool isfunc = false;
2301 ast_value *var = NULL;
2302 ast_value *fld = NULL;
2303 bool cleanvar = false;
2308 ast_expression *olddecl;
2316 bool isfield = false;
2322 if (parser->tok == '.') {
2324 if (!parser_next(parser)) {
2325 parseerror(parser, "expected typename for field definition");
2330 basetype = parser_token(parser)->constval.t;
2332 if (!parser_next(parser)) {
2333 parseerror(parser, "expected variable definition");
2337 typevar = parse_type(parser, basetype, &isfunc);
2348 ve[0].name = ve[1].name = ve[2].name = NULL;
2349 ve[0].var = ve[1].var = ve[2].var = NULL;
2351 ctx = parser_ctx(parser);
2352 var = ast_value_copy(typevar);
2356 parseerror(parser, "failed to create variable");
2361 if (parser->tok != TOKEN_IDENT) {
2362 parseerror(parser, "expected variable name");
2368 bool was_end = false;
2369 if (!strcmp(parser_tokval(parser), "end_sys_globals")) {
2370 parser->crc_globals = parser->globals_count;
2373 else if (!strcmp(parser_tokval(parser), "end_sys_fields")) {
2374 parser->crc_fields = parser->fields_count;
2377 if (isfield && was_end) {
2378 if (parsewarning(parser, WARN_END_SYS_FIELDS,
2379 "global '%s' hint should not be a field",
2380 parser_tokval(parser)))
2389 if (!ast_value_set_name(var, parser_tokval(parser))) {
2390 parseerror(parser, "failed to set variable name\n");
2396 /* a function was defined */
2398 ast_value *proto = NULL;
2402 olddecl = parser_find_global(parser, parser_tokval(parser));
2404 olddecl = parser_find_local(parser, parser_tokval(parser), parser->blocklocal, &dummy);
2407 /* we had a prototype */
2408 if (!ast_istype(olddecl, ast_value)) {
2412 parseerror(parser, "cannot declare a function with the same name as a vector's member: %s",
2413 parser_tokval(parser));
2418 proto = (ast_value*)olddecl;
2421 /* turn var into a value of TYPE_FUNCTION, with the old var
2424 fval = ast_value_new(ctx, var->name, TYPE_FUNCTION);
2430 fval->expression.next = (ast_expression*)var;
2431 MEM_VECTOR_MOVE(&var->expression, params, &fval->expression, params);
2432 fval->expression.variadic = var->expression.variadic;
2435 /* we compare the type late here, but it's easier than
2436 * messing with the parameter-vector etc. earlier
2440 if (!ast_compare_type((ast_expression*)proto, (ast_expression*)fval)) {
2441 parseerror(parser, "conflicting types for `%s`, previous declaration was here: %s:%i",
2443 ast_ctx(proto).file, ast_ctx(proto).line);
2444 ast_value_delete(fval);
2448 /* copy over the parameter names */
2449 for (param = 0; param < fval->expression.params_count; ++param)
2450 ast_value_set_name(proto->expression.params[param], fval->expression.params[param]->name);
2451 /* copy the new context */
2452 ast_ctx(proto) = ast_ctx(fval);
2454 /* now ditch the rest of the new data */
2455 ast_value_delete(fval);
2465 fld = ast_value_new(ctx, var->name, TYPE_FIELD);
2466 fld->expression.next = (ast_expression*)var;
2477 olddecl = parser_find_global(parser, var->name);
2480 parseerror(parser, "global `%s` already declared here: %s:%i",
2481 var->name, ast_ctx(olddecl).file, (int)ast_ctx(olddecl).line);
2485 else if (opts_standard == COMPILER_QCC) {
2486 parseerror(parser, "cannot declare a field and a global of the same name with -std=qcc");
2487 parseerror(parser, "global `%s` already declared here: %s:%i",
2488 var->name, ast_ctx(olddecl).file, (int)ast_ctx(olddecl).line);
2493 olddecl = parser_find_field(parser, var->name);
2494 if (olddecl && opts_standard == COMPILER_QCC) {
2496 parseerror(parser, "cannot declare a field and a global of the same name with -std=qcc");
2497 parseerror(parser, "field `%s` already declared here: %s:%i",
2498 var->name, ast_ctx(olddecl).file, (int)ast_ctx(olddecl).line);
2504 if (parsewarning(parser, WARN_FIELD_REDECLARED, "field `%s` already declared here: %s:%i",
2505 var->name, ast_ctx(olddecl).file, (int)ast_ctx(olddecl).line))
2510 if (!ast_compare_type(olddecl, (ast_expression*)var)) {
2511 parseerror(parser, "field %s has previously been declared with a different type here: %s:%i",
2512 var->name, ast_ctx(olddecl).file, (int)ast_ctx(olddecl).line);
2522 parseerror(parser, "field `%s` already declared here: %s:%i",
2523 var->name, ast_ctx(olddecl).file, (int)ast_ctx(olddecl).line);
2528 else /* if it's a local: */
2530 olddecl = parser_find_local(parser, var->name, parser->blocklocal, &isparam);
2531 if (opts_standard == COMPILER_GMQCC)
2536 parseerror(parser, "local `%s` already declared here: %s:%i",
2537 var->name, ast_ctx(olddecl).file, (int)ast_ctx(olddecl).line);
2543 if( (!isparam && olddecl) ||
2544 (olddecl = parser_find_local(parser, var->name, 0, &isparam))
2547 if (parsewarning(parser, WARN_LOCAL_SHADOWS,
2548 "local `%s` is shadowing a parameter", var->name))
2550 parseerror(parser, "local `%s` already declared here: %s:%i",
2551 var->name, ast_ctx(olddecl).file, (int)ast_ctx(olddecl).line);
2562 parsewarning(parser, WARN_LOCAL_SHADOWS,
2563 "a parameter is shadowing local `%s`", var->name))
2565 ast_value_delete(var);
2572 parseerror(parser, "local `%s` already declared here: %s:%i",
2573 var->name, ast_ctx(olddecl).file, (int)ast_ctx(olddecl).line);
2574 ast_value_delete(var);
2579 ast_value_delete(var);
2589 varent.name = util_strdup(var->name);
2590 varent.var = (ast_expression*)var;
2594 if (!(retval = parser_t_globals_add(parser, varent)))
2598 if (!(retval = parser_t_fields_add(parser, varent)))
2602 if (!(retval = parser_t_locals_add(parser, varent)))
2604 if (!(retval = ast_block_locals_add(localblock, var))) {
2605 parser->locals_count--;
2610 if (fld->expression.vtype == TYPE_VECTOR)
2613 if (!create_vector_members(parser, var, ve)) {
2619 for (e = 0; e < 3; ++e) {
2621 if (!(retval = parser_t_globals_add(parser, ve[e])))
2625 if (!(retval = parser_t_fields_add(parser, ve[e])))
2630 parser->globals_count -= e+1;
2634 for (e = 0; e < 3; ++e) {
2635 if (!(retval = parser_t_locals_add(parser, ve[e])))
2637 if (!(retval = ast_block_collect(localblock, ve[e].var)))
2639 ve[e].var = NULL; /* from here it's being collected in the block */
2642 parser->locals_count -= e+1;
2643 localblock->locals_count--;
2647 ve[0].name = ve[1].name = ve[2].name = NULL;
2648 ve[0].var = ve[1].var = ve[2].var = NULL;
2655 if (!(retval = parser_next(parser)))
2658 if (parser->tok == ';') {
2659 ast_value_delete(typevar);
2660 return parser_next(parser);
2663 if (parser->tok == ',') {
2665 if (!(retval = parser_next(parser)))
2670 if (!localblock && isfield) {
2671 parseerror(parser, "missing semicolon");
2672 ast_value_delete(typevar);
2676 /* NOTE: only 'typevar' needs to be deleted from here on, so 'cleanup' won't be used
2677 * to avoid having too many gotos
2679 if (localblock && opts_standard == COMPILER_QCC) {
2680 if (parsewarning(parser, WARN_LOCAL_CONSTANTS,
2681 "initializing expression turns variable `%s` into a constant in this standard",
2684 ast_value_delete(typevar);
2689 if (parser->tok != '=') {
2690 if (opts_standard == COMPILER_QCC)
2691 parseerror(parser, "missing semicolon");
2693 parseerror(parser, "missing semicolon or initializer");
2694 ast_value_delete(typevar);
2698 if (!parser_next(parser)) {
2699 ast_value_delete(typevar);
2703 if (parser->tok == '#') {
2707 parseerror(parser, "cannot declare builtins within functions");
2708 ast_value_delete(typevar);
2712 parseerror(parser, "unexpected builtin number, '%s' is not a function", var->name);
2713 ast_value_delete(typevar);
2716 if (!parser_next(parser)) {
2717 parseerror(parser, "expected builtin number");
2718 ast_value_delete(typevar);
2721 if (parser->tok != TOKEN_INTCONST) {
2722 parseerror(parser, "builtin number must be an integer constant");
2723 ast_value_delete(typevar);
2726 if (parser_token(parser)->constval.i <= 0) {
2727 parseerror(parser, "builtin number must be positive integer greater than zero");
2728 ast_value_delete(typevar);
2732 func = ast_function_new(ast_ctx(var), var->name, var);
2734 parseerror(parser, "failed to allocate function for `%s`", var->name);
2735 ast_value_delete(typevar);
2738 if (!parser_t_functions_add(parser, func)) {
2739 parseerror(parser, "failed to allocate slot for function `%s`", var->name);
2740 ast_function_delete(func);
2741 var->constval.vfunc = NULL;
2742 ast_value_delete(typevar);
2746 func->builtin = -parser_token(parser)->constval.i;
2748 if (!parser_next(parser)) {
2749 ast_value_delete(typevar);
2753 else if (parser->tok == '{' || parser->tok == '[')
2755 ast_value_delete(typevar);
2757 parseerror(parser, "cannot declare functions within functions");
2761 if (!parse_function_body(parser, var)) {
2766 ast_expression *cexp;
2769 cexp = parse_expression_leave(parser, true);
2771 ast_value_delete(typevar);
2775 cval = (ast_value*)cexp;
2776 if (!ast_istype(cval, ast_value) || !cval->isconst)
2777 parseerror(parser, "cannot initialize a global constant variable with a non-constant expression");
2780 var->isconst = true;
2781 if (cval->expression.vtype == TYPE_STRING)
2782 var->constval.vstring = parser_strdup(cval->constval.vstring);
2784 memcpy(&var->constval, &cval->constval, sizeof(var->constval));
2789 if (parser->tok == ',') {
2794 if (parser->tok != ';') {
2795 parseerror(parser, "missing semicolon");
2796 ast_value_delete(typevar);
2800 (void)parser_next(parser);
2802 ast_value_delete(typevar);
2807 ast_delete(typevar);
2808 if (var && cleanvar) ast_delete(var);
2809 if (varent.name) mem_d(varent.name);
2810 if (ve[0].name) mem_d(ve[0].name);
2811 if (ve[1].name) mem_d(ve[1].name);
2812 if (ve[2].name) mem_d(ve[2].name);
2813 if (ve[0].var) mem_d(ve[0].var);
2814 if (ve[1].var) mem_d(ve[1].var);
2815 if (ve[2].var) mem_d(ve[2].var);
2820 static bool parser_global_statement(parser_t *parser)
2822 if (parser->tok == TOKEN_TYPENAME || parser->tok == '.')
2824 return parse_variable(parser, NULL);
2826 else if (parser->tok == TOKEN_KEYWORD)
2828 /* handle 'var' and 'const' */
2831 else if (parser->tok == '$')
2833 if (!parser_next(parser)) {
2834 parseerror(parser, "parse error");
2840 parseerror(parser, "unexpected token: %s", parser->lex->tok.value);
2846 static parser_t *parser;
2850 parser = (parser_t*)mem_a(sizeof(parser_t));
2854 memset(parser, 0, sizeof(*parser));
2858 bool parser_compile()
2860 /* initial lexer/parser state */
2861 parser->lex->flags.noops = true;
2863 if (parser_next(parser))
2865 while (parser->tok != TOKEN_EOF && parser->tok < TOKEN_ERROR)
2867 if (!parser_global_statement(parser)) {
2868 if (parser->tok == TOKEN_EOF)
2869 parseerror(parser, "unexpected eof");
2870 else if (!parser->errors)
2871 parseerror(parser, "there have been errors, bailing out");
2872 lex_close(parser->lex);
2878 parseerror(parser, "parse error");
2879 lex_close(parser->lex);
2884 lex_close(parser->lex);
2887 return !parser->errors;
2890 bool parser_compile_file(const char *filename)
2892 parser->lex = lex_open(filename);
2894 con_out("failed to open file \"%s\"\n", filename);
2897 return parser_compile();
2900 bool parser_compile_string(const char *name, const char *str)
2902 parser->lex = lex_open_string(str, strlen(str), name);
2904 con_out("failed to create lexer for string \"%s\"\n", name);
2907 return parser_compile();
2910 void parser_cleanup()
2913 for (i = 0; i < parser->functions_count; ++i) {
2914 ast_delete(parser->functions[i]);
2916 for (i = 0; i < parser->imm_vector_count; ++i) {
2917 ast_delete(parser->imm_vector[i]);
2919 for (i = 0; i < parser->imm_string_count; ++i) {
2920 ast_delete(parser->imm_string[i]);
2922 for (i = 0; i < parser->imm_float_count; ++i) {
2923 ast_delete(parser->imm_float[i]);
2925 for (i = 0; i < parser->fields_count; ++i) {
2926 ast_delete(parser->fields[i].var);
2927 mem_d(parser->fields[i].name);
2929 for (i = 0; i < parser->globals_count; ++i) {
2930 ast_delete(parser->globals[i].var);
2931 mem_d(parser->globals[i].name);
2933 MEM_VECTOR_CLEAR(parser, functions);
2934 MEM_VECTOR_CLEAR(parser, imm_vector);
2935 MEM_VECTOR_CLEAR(parser, imm_string);
2936 MEM_VECTOR_CLEAR(parser, imm_float);
2937 MEM_VECTOR_CLEAR(parser, globals);
2938 MEM_VECTOR_CLEAR(parser, fields);
2939 MEM_VECTOR_CLEAR(parser, locals);
2944 static uint16_t progdefs_crc_sum(uint16_t old, const char *str)
2946 return util_crc16(old, str, strlen(str));
2949 static void progdefs_crc_file(const char *str)
2951 /* write to progdefs.h here */
2954 static uint16_t progdefs_crc_both(uint16_t old, const char *str)
2956 old = progdefs_crc_sum(old, str);
2957 progdefs_crc_file(str);
2961 static void generate_checksum(parser_t *parser)
2963 uint16_t crc = 0xFFFF;
2966 crc = progdefs_crc_both(crc, "\n/* file generated by qcc, do not modify */\n\ntypedef struct\n{");
2967 crc = progdefs_crc_sum(crc, "\tint\tpad[28];\n");
2969 progdefs_crc_file("\tint\tpad;\n");
2970 progdefs_crc_file("\tint\tofs_return[3];\n");
2971 progdefs_crc_file("\tint\tofs_parm0[3];\n");
2972 progdefs_crc_file("\tint\tofs_parm1[3];\n");
2973 progdefs_crc_file("\tint\tofs_parm2[3];\n");
2974 progdefs_crc_file("\tint\tofs_parm3[3];\n");
2975 progdefs_crc_file("\tint\tofs_parm4[3];\n");
2976 progdefs_crc_file("\tint\tofs_parm5[3];\n");
2977 progdefs_crc_file("\tint\tofs_parm6[3];\n");
2978 progdefs_crc_file("\tint\tofs_parm7[3];\n");
2980 for (i = 0; i < parser->crc_globals; ++i) {
2981 if (!ast_istype(parser->globals[i].var, ast_value))
2983 switch (parser->globals[i].var->expression.vtype) {
2984 case TYPE_FLOAT: crc = progdefs_crc_both(crc, "\tfloat\t"); break;
2985 case TYPE_VECTOR: crc = progdefs_crc_both(crc, "\tvec3_t\t"); break;
2986 case TYPE_STRING: crc = progdefs_crc_both(crc, "\tstring_t\t"); break;
2987 case TYPE_FUNCTION: crc = progdefs_crc_both(crc, "\tfunc_t\t"); break;
2989 crc = progdefs_crc_both(crc, "\tint\t");
2992 crc = progdefs_crc_both(crc, parser->globals[i].name);
2993 crc = progdefs_crc_both(crc, ";\n");
2995 crc = progdefs_crc_both(crc, "} globalvars_t;\n\ntypedef struct\n{\n");
2996 for (i = 0; i < parser->crc_fields; ++i) {
2997 if (!ast_istype(parser->fields[i].var, ast_value))
2999 switch (parser->fields[i].var->expression.next->expression.vtype) {
3000 case TYPE_FLOAT: crc = progdefs_crc_both(crc, "\tfloat\t"); break;
3001 case TYPE_VECTOR: crc = progdefs_crc_both(crc, "\tvec3_t\t"); break;
3002 case TYPE_STRING: crc = progdefs_crc_both(crc, "\tstring_t\t"); break;
3003 case TYPE_FUNCTION: crc = progdefs_crc_both(crc, "\tfunc_t\t"); break;
3005 crc = progdefs_crc_both(crc, "\tint\t");
3008 crc = progdefs_crc_both(crc, parser->fields[i].name);
3009 crc = progdefs_crc_both(crc, ";\n");
3011 crc = progdefs_crc_both(crc, "} entvars_t;\n\n");
3016 bool parser_finish(const char *output)
3022 if (!parser->errors)
3024 ir = ir_builder_new("gmqcc_out");
3026 con_out("failed to allocate builder\n");
3030 for (i = 0; i < parser->fields_count; ++i) {
3033 if (!ast_istype(parser->fields[i].var, ast_value))
3035 field = (ast_value*)parser->fields[i].var;
3036 isconst = field->isconst;
3037 field->isconst = false;
3038 if (!ast_global_codegen((ast_value*)field, ir)) {
3039 con_out("failed to generate field %s\n", field->name);
3040 ir_builder_delete(ir);
3045 ast_expression *subtype;
3046 field->isconst = true;
3047 subtype = field->expression.next;
3048 ifld = ir_builder_create_field(ir, field->name, subtype->expression.vtype);
3049 if (subtype->expression.vtype == TYPE_FIELD)
3050 ifld->fieldtype = subtype->expression.next->expression.vtype;
3051 else if (subtype->expression.vtype == TYPE_FUNCTION)
3052 ifld->outtype = subtype->expression.next->expression.vtype;
3053 (void)!ir_value_set_field(field->ir_v, ifld);
3056 for (i = 0; i < parser->globals_count; ++i) {
3058 if (!ast_istype(parser->globals[i].var, ast_value))
3060 asvalue = (ast_value*)(parser->globals[i].var);
3061 if (!asvalue->uses && !asvalue->isconst && asvalue->expression.vtype != TYPE_FUNCTION) {
3062 if (strcmp(asvalue->name, "end_sys_globals") &&
3063 strcmp(asvalue->name, "end_sys_fields"))
3065 retval = retval && !genwarning(ast_ctx(asvalue), WARN_UNUSED_VARIABLE,
3066 "unused global: `%s`", asvalue->name);
3069 if (!ast_global_codegen(asvalue, ir)) {
3070 con_out("failed to generate global %s\n", parser->globals[i].name);
3071 ir_builder_delete(ir);
3075 for (i = 0; i < parser->imm_float_count; ++i) {
3076 if (!ast_global_codegen(parser->imm_float[i], ir)) {
3077 con_out("failed to generate global %s\n", parser->imm_float[i]->name);
3078 ir_builder_delete(ir);
3082 for (i = 0; i < parser->imm_string_count; ++i) {
3083 if (!ast_global_codegen(parser->imm_string[i], ir)) {
3084 con_out("failed to generate global %s\n", parser->imm_string[i]->name);
3085 ir_builder_delete(ir);
3089 for (i = 0; i < parser->imm_vector_count; ++i) {
3090 if (!ast_global_codegen(parser->imm_vector[i], ir)) {
3091 con_out("failed to generate global %s\n", parser->imm_vector[i]->name);
3092 ir_builder_delete(ir);
3096 for (i = 0; i < parser->functions_count; ++i) {
3097 if (!ast_function_codegen(parser->functions[i], ir)) {
3098 con_out("failed to generate function %s\n", parser->functions[i]->name);
3099 ir_builder_delete(ir);
3102 if (!ir_function_finalize(parser->functions[i]->ir_func)) {
3103 con_out("failed to finalize function %s\n", parser->functions[i]->name);
3104 ir_builder_delete(ir);
3111 ir_builder_dump(ir, con_out);
3113 generate_checksum(parser);
3115 if (!ir_builder_generate(ir, output)) {
3116 con_out("*** failed to generate output file\n");
3117 ir_builder_delete(ir);
3122 ir_builder_delete(ir);
3126 con_out("*** there were compile errors\n");