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 var = ast_value_new(ctx, "<unnamed>", vtype);
421 var->expression.variadic = variadic;
422 MEM_VECTOR_MOVE(¶ms, p, &var->expression, params);
425 for (i = 0; i < params.p_count; ++i)
426 ast_value_delete(params.p[i]);
427 MEM_VECTOR_CLEAR(¶ms, p);
433 size_t etype; /* 0 = expression, others are operators */
437 ast_block *block; /* for commas and function calls */
442 MEM_VECTOR_MAKE(sy_elem, out);
443 MEM_VECTOR_MAKE(sy_elem, ops);
445 MEM_VEC_FUNCTIONS(shunt, sy_elem, out)
446 MEM_VEC_FUNCTIONS(shunt, sy_elem, ops)
448 static sy_elem syexp(lex_ctx ctx, ast_expression *v) {
458 static sy_elem syblock(lex_ctx ctx, ast_block *v) {
461 e.out = (ast_expression*)v;
468 static sy_elem syop(lex_ctx ctx, const oper_info *op) {
470 e.etype = 1 + (op - operators);
478 static sy_elem syparen(lex_ctx ctx, int p, size_t off) {
490 # define DEBUGSHUNTDO(x) x
492 # define DEBUGSHUNTDO(x)
495 static bool parser_sy_pop(parser_t *parser, shunt *sy)
499 ast_expression *out = NULL;
500 ast_expression *exprs[3];
501 ast_block *blocks[3];
502 ast_value *asvalue[3];
504 qcint generated_op = 0;
506 if (!sy->ops_count) {
507 parseerror(parser, "internal error: missing operator");
511 if (sy->ops[sy->ops_count-1].paren) {
512 parseerror(parser, "unmatched parenthesis");
516 op = &operators[sy->ops[sy->ops_count-1].etype - 1];
517 ctx = sy->ops[sy->ops_count-1].ctx;
519 DEBUGSHUNTDO(printf("apply %s\n", op->op));
521 if (sy->out_count < op->operands) {
522 parseerror(parser, "internal error: not enough operands: %i (operator %s (%i))", sy->out_count,
523 op->op, (int)op->id);
529 sy->out_count -= op->operands;
530 for (i = 0; i < op->operands; ++i) {
531 exprs[i] = sy->out[sy->out_count+i].out;
532 blocks[i] = sy->out[sy->out_count+i].block;
533 asvalue[i] = (ast_value*)exprs[i];
536 if (blocks[0] && !blocks[0]->exprs_count && op->id != opid1(',')) {
537 parseerror(parser, "internal error: operator cannot be applied on empty blocks");
541 #define NotSameType(T) \
542 (exprs[0]->expression.vtype != exprs[1]->expression.vtype || \
543 exprs[0]->expression.vtype != T)
544 #define CanConstFold1(A) \
545 (ast_istype((A), ast_value) && ((ast_value*)(A))->isconst)
546 #define CanConstFold(A, B) \
547 (CanConstFold1(A) && CanConstFold1(B))
548 #define ConstV(i) (asvalue[(i)]->constval.vvec)
549 #define ConstF(i) (asvalue[(i)]->constval.vfloat)
550 #define ConstS(i) (asvalue[(i)]->constval.vstring)
554 parseerror(parser, "internal error: unhandled operator: %s (%i)", op->op, (int)op->id);
558 if (exprs[0]->expression.vtype == TYPE_ENTITY) {
559 if (exprs[1]->expression.vtype != TYPE_FIELD) {
560 parseerror(parser, "type error: right hand of member-operand should be an entity-field");
563 out = (ast_expression*)ast_entfield_new(ctx, exprs[0], exprs[1]);
565 else if (exprs[0]->expression.vtype == TYPE_VECTOR) {
566 parseerror(parser, "internal error: vector access is not supposed to be handled at this point");
570 parseerror(parser, "type error: member-of operator on something that is not an entity or vector");
577 if (!ast_block_exprs_add(blocks[0], exprs[1]))
580 blocks[0] = ast_block_new(ctx);
581 if (!ast_block_exprs_add(blocks[0], exprs[0]) ||
582 !ast_block_exprs_add(blocks[0], exprs[1]))
587 if (!ast_block_set_type(blocks[0], exprs[1]))
590 sy->out[sy->out_count++] = syblock(ctx, blocks[0]);
594 switch (exprs[0]->expression.vtype) {
596 if (CanConstFold1(exprs[0]))
597 out = (ast_expression*)parser_const_float(parser, -ConstF(0));
599 out = (ast_expression*)ast_binary_new(ctx, INSTR_SUB_F,
600 (ast_expression*)parser_const_float_0(parser),
604 if (CanConstFold1(exprs[0]))
605 out = (ast_expression*)parser_const_vector_f(parser,
606 -ConstV(0).x, -ConstV(0).y, -ConstV(0).z);
608 out = (ast_expression*)ast_binary_new(ctx, INSTR_SUB_V,
609 (ast_expression*)parser_const_vector_0(parser),
613 parseerror(parser, "invalid types used in expression: cannot negate type %s",
614 type_name[exprs[0]->expression.vtype]);
620 switch (exprs[0]->expression.vtype) {
622 if (CanConstFold1(exprs[0]))
623 out = (ast_expression*)parser_const_float(parser, !ConstF(0));
625 out = (ast_expression*)ast_unary_new(ctx, INSTR_NOT_F, exprs[0]);
628 if (CanConstFold1(exprs[0]))
629 out = (ast_expression*)parser_const_float(parser,
630 (!ConstV(0).x && !ConstV(0).y && !ConstV(0).z));
632 out = (ast_expression*)ast_unary_new(ctx, INSTR_NOT_V, exprs[0]);
635 if (CanConstFold1(exprs[0]))
636 out = (ast_expression*)parser_const_float(parser, !ConstS(0) || !*ConstS(0));
638 out = (ast_expression*)ast_unary_new(ctx, INSTR_NOT_S, exprs[0]);
640 /* we don't constant-fold NOT for these types */
642 out = (ast_expression*)ast_unary_new(ctx, INSTR_NOT_ENT, exprs[0]);
645 out = (ast_expression*)ast_unary_new(ctx, INSTR_NOT_FNC, exprs[0]);
648 parseerror(parser, "invalid types used in expression: cannot logically negate type %s",
649 type_name[exprs[0]->expression.vtype]);
655 if (exprs[0]->expression.vtype != exprs[1]->expression.vtype ||
656 (exprs[0]->expression.vtype != TYPE_VECTOR && exprs[0]->expression.vtype != TYPE_FLOAT) )
658 parseerror(parser, "invalid types used in expression: cannot add type %s and %s",
659 type_name[exprs[0]->expression.vtype],
660 type_name[exprs[1]->expression.vtype]);
663 switch (exprs[0]->expression.vtype) {
665 if (CanConstFold(exprs[0], exprs[1]))
667 out = (ast_expression*)parser_const_float(parser, ConstF(0) + ConstF(1));
670 out = (ast_expression*)ast_binary_new(ctx, INSTR_ADD_F, exprs[0], exprs[1]);
673 if (CanConstFold(exprs[0], exprs[1]))
674 out = (ast_expression*)parser_const_vector(parser, vec3_add(ConstV(0), ConstV(1)));
676 out = (ast_expression*)ast_binary_new(ctx, INSTR_ADD_V, exprs[0], exprs[1]);
679 parseerror(parser, "invalid types used in expression: cannot add type %s and %s",
680 type_name[exprs[0]->expression.vtype],
681 type_name[exprs[1]->expression.vtype]);
686 if (exprs[0]->expression.vtype != exprs[1]->expression.vtype ||
687 (exprs[0]->expression.vtype != TYPE_VECTOR && exprs[0]->expression.vtype != TYPE_FLOAT) )
689 parseerror(parser, "invalid types used in expression: cannot subtract type %s from %s",
690 type_name[exprs[1]->expression.vtype],
691 type_name[exprs[0]->expression.vtype]);
694 switch (exprs[0]->expression.vtype) {
696 if (CanConstFold(exprs[0], exprs[1]))
697 out = (ast_expression*)parser_const_float(parser, ConstF(0) - ConstF(1));
699 out = (ast_expression*)ast_binary_new(ctx, INSTR_SUB_F, exprs[0], exprs[1]);
702 if (CanConstFold(exprs[0], exprs[1]))
703 out = (ast_expression*)parser_const_vector(parser, vec3_sub(ConstV(0), ConstV(1)));
705 out = (ast_expression*)ast_binary_new(ctx, INSTR_SUB_V, exprs[0], exprs[1]);
708 parseerror(parser, "invalid types used in expression: cannot subtract type %s from %s",
709 type_name[exprs[1]->expression.vtype],
710 type_name[exprs[0]->expression.vtype]);
715 if (exprs[0]->expression.vtype != exprs[1]->expression.vtype &&
716 exprs[0]->expression.vtype != TYPE_VECTOR &&
717 exprs[0]->expression.vtype != TYPE_FLOAT &&
718 exprs[1]->expression.vtype != TYPE_VECTOR &&
719 exprs[1]->expression.vtype != TYPE_FLOAT)
721 parseerror(parser, "invalid types used in expression: cannot multiply types %s and %s",
722 type_name[exprs[1]->expression.vtype],
723 type_name[exprs[0]->expression.vtype]);
726 switch (exprs[0]->expression.vtype) {
728 if (exprs[1]->expression.vtype == TYPE_VECTOR)
730 if (CanConstFold(exprs[0], exprs[1]))
731 out = (ast_expression*)parser_const_vector(parser, vec3_mulvf(ConstV(1), ConstF(0)));
733 out = (ast_expression*)ast_binary_new(ctx, INSTR_MUL_FV, exprs[0], exprs[1]);
737 if (CanConstFold(exprs[0], exprs[1]))
738 out = (ast_expression*)parser_const_float(parser, ConstF(0) * ConstF(1));
740 out = (ast_expression*)ast_binary_new(ctx, INSTR_MUL_F, exprs[0], exprs[1]);
744 if (exprs[1]->expression.vtype == TYPE_FLOAT)
746 if (CanConstFold(exprs[0], exprs[1]))
747 out = (ast_expression*)parser_const_vector(parser, vec3_mulvf(ConstV(0), ConstF(1)));
749 out = (ast_expression*)ast_binary_new(ctx, INSTR_MUL_VF, exprs[0], exprs[1]);
753 if (CanConstFold(exprs[0], exprs[1]))
754 out = (ast_expression*)parser_const_float(parser, vec3_mulvv(ConstV(0), ConstV(1)));
756 out = (ast_expression*)ast_binary_new(ctx, INSTR_MUL_V, exprs[0], exprs[1]);
760 parseerror(parser, "invalid types used in expression: cannot multiply types %s and %s",
761 type_name[exprs[1]->expression.vtype],
762 type_name[exprs[0]->expression.vtype]);
767 if (NotSameType(TYPE_FLOAT)) {
768 parseerror(parser, "invalid types used in expression: cannot divide types %s and %s",
769 type_name[exprs[0]->expression.vtype],
770 type_name[exprs[1]->expression.vtype]);
773 if (CanConstFold(exprs[0], exprs[1]))
774 out = (ast_expression*)parser_const_float(parser, ConstF(0) / ConstF(1));
776 out = (ast_expression*)ast_binary_new(ctx, INSTR_DIV_F, exprs[0], exprs[1]);
780 parseerror(parser, "qc does not have a modulo operator");
784 if (NotSameType(TYPE_FLOAT)) {
785 parseerror(parser, "invalid types used in expression: cannot perform bit operations between types %s and %s",
786 type_name[exprs[0]->expression.vtype],
787 type_name[exprs[1]->expression.vtype]);
790 if (CanConstFold(exprs[0], exprs[1]))
791 out = (ast_expression*)parser_const_float(parser,
792 (op->id == opid1('|') ? (float)( ((qcint)ConstF(0)) | ((qcint)ConstF(1)) ) :
793 (float)( ((qcint)ConstF(0)) & ((qcint)ConstF(1)) ) ));
795 out = (ast_expression*)ast_binary_new(ctx,
796 (op->id == opid1('|') ? INSTR_BITOR : INSTR_BITAND),
800 parseerror(parser, "TODO: bitxor");
805 case opid3('<','<','='):
806 case opid3('>','>','='):
807 parseerror(parser, "TODO: shifts");
811 generated_op += 1; /* INSTR_OR */
813 generated_op += INSTR_AND;
814 if (NotSameType(TYPE_FLOAT)) {
815 parseerror(parser, "invalid types used in expression: cannot perform logical operations between types %s and %s",
816 type_name[exprs[0]->expression.vtype],
817 type_name[exprs[1]->expression.vtype]);
818 parseerror(parser, "TODO: logical ops for arbitrary types using INSTR_NOT");
819 parseerror(parser, "TODO: optional early out");
822 if (opts_standard == COMPILER_GMQCC)
823 printf("TODO: early out logic\n");
824 if (CanConstFold(exprs[0], exprs[1]))
825 out = (ast_expression*)parser_const_float(parser,
826 (generated_op == INSTR_OR ? (ConstF(0) || ConstF(1)) : (ConstF(0) && ConstF(1))));
828 out = (ast_expression*)ast_binary_new(ctx, generated_op, exprs[0], exprs[1]);
832 generated_op += 1; /* INSTR_GT */
834 generated_op += 1; /* INSTR_LT */
835 case opid2('>', '='):
836 generated_op += 1; /* INSTR_GE */
837 case opid2('<', '='):
838 generated_op += INSTR_LE;
839 if (NotSameType(TYPE_FLOAT)) {
840 parseerror(parser, "invalid types used in expression: cannot perform comparison between types %s and %s",
841 type_name[exprs[0]->expression.vtype],
842 type_name[exprs[1]->expression.vtype]);
845 out = (ast_expression*)ast_binary_new(ctx, generated_op, exprs[0], exprs[1]);
847 case opid2('!', '='):
848 if (exprs[0]->expression.vtype != exprs[1]->expression.vtype) {
849 parseerror(parser, "invalid types used in expression: cannot perform comparison between types %s and %s",
850 type_name[exprs[0]->expression.vtype],
851 type_name[exprs[1]->expression.vtype]);
854 out = (ast_expression*)ast_binary_new(ctx, type_ne_instr[exprs[0]->expression.vtype], exprs[0], exprs[1]);
856 case opid2('=', '='):
857 if (exprs[0]->expression.vtype != exprs[1]->expression.vtype) {
858 parseerror(parser, "invalid types used in expression: cannot perform comparison between types %s and %s",
859 type_name[exprs[0]->expression.vtype],
860 type_name[exprs[1]->expression.vtype]);
863 out = (ast_expression*)ast_binary_new(ctx, type_eq_instr[exprs[0]->expression.vtype], exprs[0], exprs[1]);
867 if (ast_istype(exprs[0], ast_entfield))
868 assignop = type_storep_instr[exprs[0]->expression.vtype];
870 assignop = type_store_instr[exprs[0]->expression.vtype];
871 out = (ast_expression*)ast_store_new(ctx, assignop, exprs[0], exprs[1]);
875 if (exprs[0]->expression.vtype != exprs[1]->expression.vtype ||
876 (exprs[0]->expression.vtype != TYPE_VECTOR && exprs[0]->expression.vtype != TYPE_FLOAT) )
878 parseerror(parser, "invalid types used in expression: cannot add or subtract type %s and %s",
879 type_name[exprs[0]->expression.vtype],
880 type_name[exprs[1]->expression.vtype]);
883 if (ast_istype(exprs[0], ast_entfield))
884 assignop = type_storep_instr[exprs[0]->expression.vtype];
886 assignop = type_store_instr[exprs[0]->expression.vtype];
887 switch (exprs[0]->expression.vtype) {
889 out = (ast_expression*)ast_binstore_new(ctx, assignop,
890 (op->id == opid2('+','=') ? INSTR_ADD_F : INSTR_SUB_F),
894 out = (ast_expression*)ast_binstore_new(ctx, assignop,
895 (op->id == opid2('+','=') ? INSTR_ADD_V : INSTR_SUB_V),
899 parseerror(parser, "invalid types used in expression: cannot add or subtract type %s and %s",
900 type_name[exprs[0]->expression.vtype],
901 type_name[exprs[1]->expression.vtype]);
909 parseerror(parser, "failed to apply operand %s", op->op);
913 DEBUGSHUNTDO(printf("applied %s\n", op->op));
914 sy->out[sy->out_count++] = syexp(ctx, out);
918 static bool parser_close_call(parser_t *parser, shunt *sy)
920 /* was a function call */
928 fid = sy->ops[sy->ops_count].off;
930 /* out[fid] is the function
931 * everything above is parameters...
933 * 1 params = ast_expression
937 if (sy->out_count < 1 || sy->out_count <= fid) {
938 parseerror(parser, "internal error: function call needs function and parameter list...");
942 fun = sy->out[fid].out;
944 call = ast_call_new(sy->ops[sy->ops_count].ctx, fun);
946 parseerror(parser, "out of memory");
950 if (fid+1 == sy->out_count) {
953 } else if (fid+2 == sy->out_count) {
956 params = sy->out[sy->out_count].block;
960 if (!ast_call_params_add(call, sy->out[sy->out_count].out)) {
961 ast_delete(sy->out[sy->out_count].out);
962 parseerror(parser, "out of memory");
966 paramcount = params->exprs_count;
967 MEM_VECTOR_MOVE(params, exprs, call, params);
970 if (!ast_call_check_types(call))
973 parseerror(parser, "invalid function call");
977 /* overwrite fid, the function, with a call */
978 sy->out[fid] = syexp(call->expression.node.context, (ast_expression*)call);
980 if (fun->expression.vtype != TYPE_FUNCTION) {
981 parseerror(parser, "not a function (%s)", type_name[fun->expression.vtype]);
985 if (!fun->expression.next) {
986 parseerror(parser, "could not determine function return type");
989 if (fun->expression.params_count != paramcount &&
990 !(fun->expression.variadic &&
991 fun->expression.params_count < paramcount))
994 const char *fewmany = (fun->expression.params_count > paramcount) ? "few" : "many";
996 fval = (ast_istype(fun, ast_value) ? ((ast_value*)fun) : NULL);
997 if (opts_standard == COMPILER_GMQCC)
1000 parseerror(parser, "too %s parameters for call to %s: expected %i, got %i\n"
1001 " -> `%s` has been declared here: %s:%i",
1002 fewmany, fval->name, (int)fun->expression.params_count, (int)paramcount,
1003 fval->name, ast_ctx(fun).file, (int)ast_ctx(fun).line);
1005 parseerror(parser, "too %s parameters for function call: expected %i, got %i\n"
1006 " -> `%s` has been declared here: %s:%i",
1007 fewmany, fval->name, (int)fun->expression.params_count, (int)paramcount,
1008 fval->name, ast_ctx(fun).file, (int)ast_ctx(fun).line);
1014 return !parsewarning(parser, WARN_TOO_FEW_PARAMETERS,
1015 "too %s parameters for call to %s: expected %i, got %i\n"
1016 " -> `%s` has been declared here: %s:%i",
1017 fewmany, fval->name, (int)fun->expression.params_count, (int)paramcount,
1018 fval->name, ast_ctx(fun).file, (int)ast_ctx(fun).line);
1020 return !parsewarning(parser, WARN_TOO_FEW_PARAMETERS,
1021 "too %s parameters for function call: expected %i, got %i\n"
1022 " -> `%s` has been declared here: %s:%i",
1023 fewmany, fval->name, (int)fun->expression.params_count, (int)paramcount,
1024 fval->name, ast_ctx(fun).file, (int)ast_ctx(fun).line);
1032 static bool parser_close_paren(parser_t *parser, shunt *sy, bool functions_only)
1034 if (!sy->ops_count) {
1035 parseerror(parser, "unmatched closing paren");
1038 /* this would for bit a + (x) because there are no operators inside (x)
1039 if (sy->ops[sy->ops_count-1].paren == 1) {
1040 parseerror(parser, "empty parenthesis expression");
1044 while (sy->ops_count) {
1045 if (sy->ops[sy->ops_count-1].paren == 'f') {
1046 if (!parser_close_call(parser, sy))
1050 if (sy->ops[sy->ops_count-1].paren == 1) {
1052 return !functions_only;
1054 if (!parser_sy_pop(parser, sy))
1060 static void parser_reclassify_token(parser_t *parser)
1063 for (i = 0; i < operator_count; ++i) {
1064 if (!strcmp(parser_tokval(parser), operators[i].op)) {
1065 parser->tok = TOKEN_OPERATOR;
1071 static ast_expression* parse_expression_leave(parser_t *parser, bool stopatcomma)
1073 ast_expression *expr = NULL;
1075 bool wantop = false;
1076 bool gotmemberof = false;
1078 /* count the parens because an if starts with one, so the
1079 * end of a condition is an unmatched closing paren
1083 MEM_VECTOR_INIT(&sy, out);
1084 MEM_VECTOR_INIT(&sy, ops);
1086 parser->lex->flags.noops = false;
1088 parser_reclassify_token(parser);
1093 gotmemberof = false;
1095 parser->memberof = 0;
1097 if (parser->tok == TOKEN_IDENT)
1099 ast_expression *var;
1101 parseerror(parser, "expected operator or end of statement");
1106 if (opts_standard == COMPILER_GMQCC)
1108 if (parser->memberof == TYPE_ENTITY) {
1109 /* still get vars first since there could be a fieldpointer */
1110 var = parser_find_var(parser, parser_tokval(parser));
1112 var = parser_find_field(parser, parser_tokval(parser));
1114 else if (parser->memberof == TYPE_VECTOR)
1116 parseerror(parser, "TODO: implement effective vector member access");
1119 else if (parser->memberof) {
1120 parseerror(parser, "namespace for member not found");
1124 var = parser_find_var(parser, parser_tokval(parser));
1126 var = parser_find_var(parser, parser_tokval(parser));
1128 var = parser_find_field(parser, parser_tokval(parser));
1131 parseerror(parser, "unexpected ident: %s", parser_tokval(parser));
1134 if (ast_istype(var, ast_value))
1135 ((ast_value*)var)->uses++;
1136 if (!shunt_out_add(&sy, syexp(parser_ctx(parser), var))) {
1137 parseerror(parser, "out of memory");
1140 DEBUGSHUNTDO(printf("push %s\n", parser_tokval(parser)));
1142 else if (parser->tok == TOKEN_FLOATCONST) {
1145 parseerror(parser, "expected operator or end of statement, got constant");
1149 val = parser_const_float(parser, (parser_token(parser)->constval.f));
1152 if (!shunt_out_add(&sy, syexp(parser_ctx(parser), (ast_expression*)val))) {
1153 parseerror(parser, "out of memory");
1156 DEBUGSHUNTDO(printf("push %g\n", parser_token(parser)->constval.f));
1158 else if (parser->tok == TOKEN_INTCONST) {
1161 parseerror(parser, "expected operator or end of statement, got constant");
1165 val = parser_const_float(parser, (double)(parser_token(parser)->constval.i));
1168 if (!shunt_out_add(&sy, syexp(parser_ctx(parser), (ast_expression*)val))) {
1169 parseerror(parser, "out of memory");
1172 DEBUGSHUNTDO(printf("push %i\n", parser_token(parser)->constval.i));
1174 else if (parser->tok == TOKEN_STRINGCONST) {
1177 parseerror(parser, "expected operator or end of statement, got constant");
1181 val = parser_const_string(parser, parser_tokval(parser));
1184 if (!shunt_out_add(&sy, syexp(parser_ctx(parser), (ast_expression*)val))) {
1185 parseerror(parser, "out of memory");
1188 DEBUGSHUNTDO(printf("push string\n"));
1190 else if (parser->tok == TOKEN_VECTORCONST) {
1193 parseerror(parser, "expected operator or end of statement, got constant");
1197 val = parser_const_vector(parser, parser_token(parser)->constval.v);
1200 if (!shunt_out_add(&sy, syexp(parser_ctx(parser), (ast_expression*)val))) {
1201 parseerror(parser, "out of memory");
1204 DEBUGSHUNTDO(printf("push '%g %g %g'\n",
1205 parser_token(parser)->constval.v.x,
1206 parser_token(parser)->constval.v.y,
1207 parser_token(parser)->constval.v.z));
1209 else if (parser->tok == '(') {
1210 parseerror(parser, "internal error: '(' should be classified as operator");
1213 else if (parser->tok == ')') {
1215 DEBUGSHUNTDO(printf("do[op] )\n"));
1219 /* we do expect an operator next */
1220 /* closing an opening paren */
1221 if (!parser_close_paren(parser, &sy, false))
1224 DEBUGSHUNTDO(printf("do[nop] )\n"));
1228 /* allowed for function calls */
1229 if (!parser_close_paren(parser, &sy, true))
1234 else if (parser->tok != TOKEN_OPERATOR) {
1236 parseerror(parser, "expected operator or end of statement");
1243 /* classify the operator */
1244 /* TODO: suffix operators */
1245 const oper_info *op;
1246 const oper_info *olast = NULL;
1248 for (o = 0; o < operator_count; ++o) {
1249 if ((!(operators[o].flags & OP_PREFIX) == wantop) &&
1250 !(operators[o].flags & OP_SUFFIX) && /* remove this */
1251 !strcmp(parser_tokval(parser), operators[o].op))
1256 if (o == operator_count) {
1257 /* no operator found... must be the end of the statement */
1260 /* found an operator */
1263 /* when declaring variables, a comma starts a new variable */
1264 if (op->id == opid1(',') && !parens && stopatcomma) {
1265 /* fixup the token */
1270 if (sy.ops_count && !sy.ops[sy.ops_count-1].paren)
1271 olast = &operators[sy.ops[sy.ops_count-1].etype-1];
1274 (op->prec < olast->prec) ||
1275 (op->assoc == ASSOC_LEFT && op->prec <= olast->prec) ) )
1277 if (!parser_sy_pop(parser, &sy))
1279 if (sy.ops_count && !sy.ops[sy.ops_count-1].paren)
1280 olast = &operators[sy.ops[sy.ops_count-1].etype-1];
1285 if (op->id == opid1('.') && opts_standard == COMPILER_GMQCC) {
1286 /* for gmqcc standard: open up the namespace of the previous type */
1287 ast_expression *prevex = sy.out[sy.out_count-1].out;
1289 parseerror(parser, "unexpected member operator");
1292 if (prevex->expression.vtype == TYPE_ENTITY)
1293 parser->memberof = TYPE_ENTITY;
1294 else if (prevex->expression.vtype == TYPE_VECTOR)
1295 parser->memberof = TYPE_VECTOR;
1297 parseerror(parser, "type error: type has no members");
1303 if (op->id == opid1('(')) {
1305 DEBUGSHUNTDO(printf("push [op] (\n"));
1307 /* we expected an operator, this is the function-call operator */
1308 if (!shunt_ops_add(&sy, syparen(parser_ctx(parser), 'f', sy.out_count-1))) {
1309 parseerror(parser, "out of memory");
1314 if (!shunt_ops_add(&sy, syparen(parser_ctx(parser), 1, 0))) {
1315 parseerror(parser, "out of memory");
1318 DEBUGSHUNTDO(printf("push [nop] (\n"));
1322 DEBUGSHUNTDO(printf("push operator %s\n", op->op));
1323 if (!shunt_ops_add(&sy, syop(parser_ctx(parser), op)))
1328 if (!parser_next(parser)) {
1331 if (parser->tok == ';' || parser->tok == ']') {
1336 while (sy.ops_count) {
1337 if (!parser_sy_pop(parser, &sy))
1341 parser->lex->flags.noops = true;
1342 if (!sy.out_count) {
1343 parseerror(parser, "empty expression");
1346 expr = sy.out[0].out;
1347 MEM_VECTOR_CLEAR(&sy, out);
1348 MEM_VECTOR_CLEAR(&sy, ops);
1349 DEBUGSHUNTDO(printf("shunt done\n"));
1353 parser->lex->flags.noops = true;
1354 MEM_VECTOR_CLEAR(&sy, out);
1355 MEM_VECTOR_CLEAR(&sy, ops);
1359 static ast_expression* parse_expression(parser_t *parser, bool stopatcomma)
1361 ast_expression *e = parse_expression_leave(parser, stopatcomma);
1364 if (!parser_next(parser)) {
1371 static bool parse_if(parser_t *parser, ast_block *block, ast_expression **out)
1374 ast_expression *cond, *ontrue, *onfalse = NULL;
1376 lex_ctx ctx = parser_ctx(parser);
1378 /* skip the 'if' and check for opening paren */
1379 if (!parser_next(parser) || parser->tok != '(') {
1380 parseerror(parser, "expected 'if' condition in parenthesis");
1383 /* parse into the expression */
1384 if (!parser_next(parser)) {
1385 parseerror(parser, "expected 'if' condition after opening paren");
1388 /* parse the condition */
1389 cond = parse_expression_leave(parser, false);
1393 if (parser->tok != ')') {
1394 parseerror(parser, "expected closing paren after 'if' condition");
1398 /* parse into the 'then' branch */
1399 if (!parser_next(parser)) {
1400 parseerror(parser, "expected statement for on-true branch of 'if'");
1404 ontrue = parse_statement_or_block(parser);
1409 /* check for an else */
1410 if (!strcmp(parser_tokval(parser), "else")) {
1411 /* parse into the 'else' branch */
1412 if (!parser_next(parser)) {
1413 parseerror(parser, "expected on-false branch after 'else'");
1418 onfalse = parse_statement_or_block(parser);
1426 ifthen = ast_ifthen_new(ctx, cond, ontrue, onfalse);
1427 *out = (ast_expression*)ifthen;
1431 static bool parse_while(parser_t *parser, ast_block *block, ast_expression **out)
1434 ast_expression *cond, *ontrue;
1436 lex_ctx ctx = parser_ctx(parser);
1438 /* skip the 'while' and check for opening paren */
1439 if (!parser_next(parser) || parser->tok != '(') {
1440 parseerror(parser, "expected 'while' condition in parenthesis");
1443 /* parse into the expression */
1444 if (!parser_next(parser)) {
1445 parseerror(parser, "expected 'while' condition after opening paren");
1448 /* parse the condition */
1449 cond = parse_expression_leave(parser, false);
1453 if (parser->tok != ')') {
1454 parseerror(parser, "expected closing paren after 'while' condition");
1458 /* parse into the 'then' branch */
1459 if (!parser_next(parser)) {
1460 parseerror(parser, "expected while-loop body");
1464 ontrue = parse_statement_or_block(parser);
1470 aloop = ast_loop_new(ctx, NULL, cond, NULL, NULL, ontrue);
1471 *out = (ast_expression*)aloop;
1475 static bool parse_dowhile(parser_t *parser, ast_block *block, ast_expression **out)
1478 ast_expression *cond, *ontrue;
1480 lex_ctx ctx = parser_ctx(parser);
1482 /* skip the 'do' and get the body */
1483 if (!parser_next(parser)) {
1484 parseerror(parser, "expected loop body");
1487 ontrue = parse_statement_or_block(parser);
1491 /* expect the "while" */
1492 if (parser->tok != TOKEN_KEYWORD ||
1493 strcmp(parser_tokval(parser), "while"))
1495 parseerror(parser, "expected 'while' and condition");
1500 /* skip the 'while' and check for opening paren */
1501 if (!parser_next(parser) || parser->tok != '(') {
1502 parseerror(parser, "expected 'while' condition in parenthesis");
1506 /* parse into the expression */
1507 if (!parser_next(parser)) {
1508 parseerror(parser, "expected 'while' condition after opening paren");
1512 /* parse the condition */
1513 cond = parse_expression_leave(parser, false);
1517 if (parser->tok != ')') {
1518 parseerror(parser, "expected closing paren after 'while' condition");
1524 if (!parser_next(parser) || parser->tok != ';') {
1525 parseerror(parser, "expected semicolon after condition");
1531 if (!parser_next(parser)) {
1532 parseerror(parser, "parse error");
1538 aloop = ast_loop_new(ctx, NULL, NULL, cond, NULL, ontrue);
1539 *out = (ast_expression*)aloop;
1543 static bool parse_for(parser_t *parser, ast_block *block, ast_expression **out)
1546 ast_expression *initexpr, *cond, *increment, *ontrue;
1547 size_t oldblocklocal;
1550 lex_ctx ctx = parser_ctx(parser);
1552 oldblocklocal = parser->blocklocal;
1553 parser->blocklocal = parser->locals_count;
1560 /* skip the 'while' and check for opening paren */
1561 if (!parser_next(parser) || parser->tok != '(') {
1562 parseerror(parser, "expected 'for' expressions in parenthesis");
1565 /* parse into the expression */
1566 if (!parser_next(parser)) {
1567 parseerror(parser, "expected 'for' initializer after opening paren");
1571 if (parser->tok == TOKEN_TYPENAME) {
1572 if (opts_standard != COMPILER_GMQCC) {
1573 if (parsewarning(parser, WARN_EXTENSIONS,
1574 "current standard does not allow variable declarations in for-loop initializers"))
1578 parseerror(parser, "TODO: assignment of new variables to be non-const");
1580 if (!parse_variable(parser, block))
1583 else if (parser->tok != ';')
1585 initexpr = parse_expression_leave(parser, false);
1590 /* move on to condition */
1591 if (parser->tok != ';') {
1592 parseerror(parser, "expected semicolon after for-loop initializer");
1595 if (!parser_next(parser)) {
1596 parseerror(parser, "expected for-loop condition");
1600 /* parse the condition */
1601 if (parser->tok != ';') {
1602 cond = parse_expression_leave(parser, false);
1607 /* move on to incrementor */
1608 if (parser->tok != ';') {
1609 parseerror(parser, "expected semicolon after for-loop initializer");
1612 if (!parser_next(parser)) {
1613 parseerror(parser, "expected for-loop condition");
1617 /* parse the incrementor */
1618 if (parser->tok != ')') {
1619 increment = parse_expression_leave(parser, false);
1622 if (!ast_istype(increment, ast_store) &&
1623 !ast_istype(increment, ast_call) &&
1624 !ast_istype(increment, ast_binstore))
1626 if (genwarning(ast_ctx(increment), WARN_EFFECTLESS_STATEMENT, "statement has no effect"))
1632 if (parser->tok != ')') {
1633 parseerror(parser, "expected closing paren after 'for-loop' incrementor");
1636 /* parse into the 'then' branch */
1637 if (!parser_next(parser)) {
1638 parseerror(parser, "expected for-loop body");
1641 ontrue = parse_statement_or_block(parser);
1646 aloop = ast_loop_new(ctx, initexpr, cond, NULL, increment, ontrue);
1647 *out = (ast_expression*)aloop;
1649 while (parser->locals_count > parser->blocklocal)
1650 retval = retval && parser_pop_local(parser);
1651 parser->blocklocal = oldblocklocal;
1654 if (initexpr) ast_delete(initexpr);
1655 if (cond) ast_delete(cond);
1656 if (increment) ast_delete(increment);
1657 while (parser->locals_count > parser->blocklocal)
1658 (void)!parser_pop_local(parser);
1659 parser->blocklocal = oldblocklocal;
1663 static bool parse_statement(parser_t *parser, ast_block *block, ast_expression **out)
1665 if (parser->tok == TOKEN_TYPENAME)
1667 /* local variable */
1669 parseerror(parser, "cannot declare a variable from here");
1672 if (opts_standard == COMPILER_QCC) {
1673 if (parsewarning(parser, WARN_EXTENSIONS, "missing 'local' keyword when declaring a local variable"))
1676 if (!parse_variable(parser, block))
1681 else if (parser->tok == TOKEN_KEYWORD)
1683 if (!strcmp(parser_tokval(parser), "local"))
1686 parseerror(parser, "cannot declare a local variable here");
1689 if (!parser_next(parser)) {
1690 parseerror(parser, "expected variable declaration");
1693 if (!parse_variable(parser, block))
1698 else if (!strcmp(parser_tokval(parser), "return"))
1700 ast_expression *exp = NULL;
1701 ast_return *ret = NULL;
1702 ast_value *expected = parser->function->vtype;
1704 if (!parser_next(parser)) {
1705 parseerror(parser, "expected return expression");
1709 if (parser->tok != ';') {
1710 exp = parse_expression(parser, false);
1714 if (exp->expression.vtype != expected->expression.next->expression.vtype) {
1715 parseerror(parser, "return with invalid expression");
1718 ret = ast_return_new(exp->expression.node.context, exp);
1724 if (!parser_next(parser))
1725 parseerror(parser, "parse error");
1726 if (expected->expression.next->expression.vtype != TYPE_VOID) {
1727 if (opts_standard != COMPILER_GMQCC)
1728 (void)!parsewarning(parser, WARN_MISSING_RETURN_VALUES, "return without value");
1730 parseerror(parser, "return without value");
1732 ret = ast_return_new(parser_ctx(parser), NULL);
1734 *out = (ast_expression*)ret;
1737 else if (!strcmp(parser_tokval(parser), "if"))
1739 return parse_if(parser, block, out);
1741 else if (!strcmp(parser_tokval(parser), "while"))
1743 return parse_while(parser, block, out);
1745 else if (!strcmp(parser_tokval(parser), "do"))
1747 return parse_dowhile(parser, block, out);
1749 else if (!strcmp(parser_tokval(parser), "for"))
1751 if (opts_standard == COMPILER_QCC) {
1752 if (parsewarning(parser, WARN_EXTENSIONS, "for loops are not recognized in the original Quake C standard, to enable try an alternate standard --std=?"))
1755 return parse_for(parser, block, out);
1757 parseerror(parser, "Unexpected keyword");
1760 else if (parser->tok == '{')
1763 inner = parse_block(parser, false);
1766 *out = (ast_expression*)inner;
1771 ast_expression *exp = parse_expression(parser, false);
1775 if (!ast_istype(exp, ast_store) &&
1776 !ast_istype(exp, ast_call) &&
1777 !ast_istype(exp, ast_binstore))
1779 if (genwarning(ast_ctx(exp), WARN_EFFECTLESS_STATEMENT, "statement has no effect"))
1786 static bool GMQCC_WARN parser_pop_local(parser_t *parser)
1789 parser->locals_count--;
1791 ve = &parser->locals[parser->locals_count];
1792 if (ast_istype(ve->var, ast_value) && !(((ast_value*)(ve->var))->uses)) {
1793 if (parsewarning(parser, WARN_UNUSED_VARIABLE, "unused variable: `%s`", ve->name))
1796 mem_d(parser->locals[parser->locals_count].name);
1800 static bool parse_block_into(parser_t *parser, ast_block *block, bool warnreturn)
1802 size_t oldblocklocal;
1805 oldblocklocal = parser->blocklocal;
1806 parser->blocklocal = parser->locals_count;
1808 if (!parser_next(parser)) { /* skip the '{' */
1809 parseerror(parser, "expected function body");
1813 while (parser->tok != TOKEN_EOF && parser->tok < TOKEN_ERROR)
1815 ast_expression *expr;
1816 if (parser->tok == '}')
1819 if (!parse_statement(parser, block, &expr)) {
1820 parseerror(parser, "parse error");
1826 if (!ast_block_exprs_add(block, expr)) {
1833 if (parser->tok != '}') {
1836 if (warnreturn && parser->function->vtype->expression.next->expression.vtype != TYPE_VOID)
1838 if (!block->exprs_count ||
1839 !ast_istype(block->exprs[block->exprs_count-1], ast_return))
1841 if (parsewarning(parser, WARN_MISSING_RETURN_VALUES, "control reaches end of non-void function")) {
1847 (void)parser_next(parser);
1851 while (parser->locals_count > parser->blocklocal)
1852 retval = retval && parser_pop_local(parser);
1853 parser->blocklocal = oldblocklocal;
1857 static ast_block* parse_block(parser_t *parser, bool warnreturn)
1860 block = ast_block_new(parser_ctx(parser));
1863 if (!parse_block_into(parser, block, warnreturn)) {
1864 ast_block_delete(block);
1870 static ast_expression* parse_statement_or_block(parser_t *parser)
1872 ast_expression *expr = NULL;
1873 if (parser->tok == '{')
1874 return (ast_expression*)parse_block(parser, false);
1875 if (!parse_statement(parser, NULL, &expr))
1881 static bool create_vector_members(parser_t *parser, ast_value *var, varentry_t *ve)
1884 size_t len = strlen(var->name);
1886 for (i = 0; i < 3; ++i) {
1887 ve[i].var = (ast_expression*)ast_member_new(ast_ctx(var), (ast_expression*)var, i);
1891 ve[i].name = (char*)mem_a(len+3);
1893 ast_delete(ve[i].var);
1897 memcpy(ve[i].name, var->name, len);
1898 ve[i].name[len] = '_';
1899 ve[i].name[len+1] = 'x'+i;
1900 ve[i].name[len+2] = 0;
1909 ast_delete(ve[i].var);
1916 static bool parse_function_body(parser_t *parser, ast_value *var)
1918 ast_block *block = NULL;
1923 ast_expression *framenum = NULL;
1924 ast_expression *nextthink = NULL;
1925 /* None of the following have to be deleted */
1926 ast_expression *fld_think, *fld_nextthink, *fld_frame;
1927 ast_expression *gbl_time, *gbl_self;
1928 bool has_frame_think;
1932 has_frame_think = false;
1933 old = parser->function;
1935 if (var->expression.variadic) {
1936 if (parsewarning(parser, WARN_VARIADIC_FUNCTION,
1937 "variadic function with implementation will not be able to access additional parameters"))
1943 if (parser->tok == '[') {
1944 /* got a frame definition: [ framenum, nextthink ]
1945 * this translates to:
1946 * self.frame = framenum;
1947 * self.nextthink = time + 0.1;
1948 * self.think = nextthink;
1952 fld_think = parser_find_field(parser, "think");
1953 fld_nextthink = parser_find_field(parser, "nextthink");
1954 fld_frame = parser_find_field(parser, "frame");
1955 if (!fld_think || !fld_nextthink || !fld_frame) {
1956 parseerror(parser, "cannot use [frame,think] notation without the required fields");
1957 parseerror(parser, "please declare the following entityfields: `frame`, `think`, `nextthink`");
1960 gbl_time = parser_find_global(parser, "time");
1961 gbl_self = parser_find_global(parser, "self");
1962 if (!gbl_time || !gbl_self) {
1963 parseerror(parser, "cannot use [frame,think] notation without the required globals");
1964 parseerror(parser, "please declare the following globals: `time`, `self`");
1968 if (!parser_next(parser))
1971 framenum = parse_expression_leave(parser, true);
1973 parseerror(parser, "expected a framenumber constant in[frame,think] notation");
1976 if (!ast_istype(framenum, ast_value) || !( (ast_value*)framenum )->isconst) {
1977 ast_unref(framenum);
1978 parseerror(parser, "framenumber in [frame,think] notation must be a constant");
1982 if (parser->tok != ',') {
1983 ast_unref(framenum);
1984 parseerror(parser, "expected comma after frame number in [frame,think] notation");
1985 parseerror(parser, "Got a %i\n", parser->tok);
1989 if (!parser_next(parser)) {
1990 ast_unref(framenum);
1994 if (parser->tok == TOKEN_IDENT && !parser_find_var(parser, parser_tokval(parser)))
1996 /* qc allows the use of not-yet-declared functions here
1997 * - this automatically creates a prototype */
1999 ast_value *thinkfunc;
2000 ast_expression *functype = fld_think->expression.next;
2002 thinkfunc = ast_value_new(parser_ctx(parser), parser_tokval(parser), functype->expression.vtype);
2003 if (!thinkfunc || !ast_type_adopt(thinkfunc, functype)) {
2004 ast_unref(framenum);
2005 parseerror(parser, "failed to create implicit prototype for `%s`", parser_tokval(parser));
2009 if (!parser_next(parser)) {
2010 ast_unref(framenum);
2011 ast_delete(thinkfunc);
2015 varent.var = (ast_expression*)thinkfunc;
2016 varent.name = util_strdup(thinkfunc->name);
2017 if (!parser_t_globals_add(parser, varent)) {
2018 ast_unref(framenum);
2019 ast_delete(thinkfunc);
2022 nextthink = (ast_expression*)thinkfunc;
2025 nextthink = parse_expression_leave(parser, true);
2027 ast_unref(framenum);
2028 parseerror(parser, "expected a think-function in [frame,think] notation");
2033 if (!ast_istype(nextthink, ast_value)) {
2034 parseerror(parser, "think-function in [frame,think] notation must be a constant");
2038 if (retval && parser->tok != ']') {
2039 parseerror(parser, "expected closing `]` for [frame,think] notation");
2043 if (retval && !parser_next(parser)) {
2047 if (retval && parser->tok != '{') {
2048 parseerror(parser, "a function body has to be declared after a [frame,think] declaration");
2053 ast_unref(nextthink);
2054 ast_unref(framenum);
2058 has_frame_think = true;
2061 block = ast_block_new(parser_ctx(parser));
2063 parseerror(parser, "failed to allocate block");
2064 if (has_frame_think) {
2065 ast_unref(nextthink);
2066 ast_unref(framenum);
2071 if (has_frame_think) {
2073 ast_expression *self_frame;
2074 ast_expression *self_nextthink;
2075 ast_expression *self_think;
2076 ast_expression *time_plus_1;
2077 ast_store *store_frame;
2078 ast_store *store_nextthink;
2079 ast_store *store_think;
2081 ctx = parser_ctx(parser);
2082 self_frame = (ast_expression*)ast_entfield_new(ctx, gbl_self, fld_frame);
2083 self_nextthink = (ast_expression*)ast_entfield_new(ctx, gbl_self, fld_nextthink);
2084 self_think = (ast_expression*)ast_entfield_new(ctx, gbl_self, fld_think);
2086 time_plus_1 = (ast_expression*)ast_binary_new(ctx, INSTR_ADD_F,
2087 gbl_time, (ast_expression*)parser_const_float(parser, 0.1));
2089 if (!self_frame || !self_nextthink || !self_think || !time_plus_1) {
2090 if (self_frame) ast_delete(self_frame);
2091 if (self_nextthink) ast_delete(self_nextthink);
2092 if (self_think) ast_delete(self_think);
2093 if (time_plus_1) ast_delete(time_plus_1);
2099 store_frame = ast_store_new(ctx, INSTR_STOREP_F, self_frame, framenum);
2100 store_nextthink = ast_store_new(ctx, INSTR_STOREP_F, self_nextthink, time_plus_1);
2101 store_think = ast_store_new(ctx, INSTR_STOREP_FNC, self_think, nextthink);
2104 ast_delete(self_frame);
2107 if (!store_nextthink) {
2108 ast_delete(self_nextthink);
2112 ast_delete(self_think);
2116 if (store_frame) ast_delete(store_frame);
2117 if (store_nextthink) ast_delete(store_nextthink);
2118 if (store_think) ast_delete(store_think);
2121 if (retval && !ast_block_exprs_add(block, (ast_expression*)store_frame)) {
2122 ast_delete(store_frame);
2123 ast_delete(store_nextthink);
2124 ast_delete(store_think);
2128 if (retval && !ast_block_exprs_add(block, (ast_expression*)store_nextthink)) {
2129 ast_delete(store_nextthink);
2130 ast_delete(store_think);
2134 if (retval && !ast_block_exprs_add(block, (ast_expression*)store_think) )
2136 ast_delete(store_think);
2142 parseerror(parser, "failed to generate code for [frame,think]");
2143 ast_unref(nextthink);
2144 ast_unref(framenum);
2150 for (parami = 0; parami < var->expression.params_count; ++parami) {
2153 ast_value *param = var->expression.params[parami];
2155 if (param->expression.vtype != TYPE_VECTOR &&
2156 (param->expression.vtype != TYPE_FIELD ||
2157 param->expression.next->expression.vtype != TYPE_VECTOR))
2162 if (!create_vector_members(parser, param, ve)) {
2163 ast_block_delete(block);
2167 for (e = 0; e < 3; ++e) {
2168 if (!parser_t_locals_add(parser, ve[e]))
2170 if (!ast_block_collect(block, ve[e].var)) {
2171 parser->locals_count--;
2174 ve[e].var = NULL; /* collected */
2177 parser->locals -= e;
2182 ast_block_delete(block);
2187 func = ast_function_new(ast_ctx(var), var->name, var);
2189 parseerror(parser, "failed to allocate function for `%s`", var->name);
2190 ast_block_delete(block);
2193 if (!parser_t_functions_add(parser, func)) {
2194 parseerror(parser, "failed to allocate slot for function `%s`", var->name);
2195 ast_block_delete(block);
2199 parser->function = func;
2200 if (!parse_block_into(parser, block, true)) {
2201 ast_block_delete(block);
2205 if (!ast_function_blocks_add(func, block)) {
2206 ast_block_delete(block);
2210 parser->function = old;
2211 while (parser->locals_count)
2212 retval = retval && parser_pop_local(parser);
2214 if (parser->tok == ';')
2215 return parser_next(parser);
2216 else if (opts_standard == COMPILER_QCC)
2217 parseerror(parser, "missing semicolon after function body (mandatory with -std=qcc)");
2221 parser->functions_count--;
2223 ast_function_delete(func);
2224 var->constval.vfunc = NULL;
2227 while (parser->locals_count) {
2228 parser->locals_count--;
2229 mem_d(parser->locals[parser->locals_count].name);
2231 parser->function = old;
2235 static bool parse_variable(parser_t *parser, ast_block *localblock)
2237 bool isfunc = false;
2240 ast_value *var = NULL;
2241 bool cleanvar = false;
2246 ast_expression *olddecl;
2257 int basetype = parser_token(parser)->constval.t;
2259 if (!parser_next(parser)) {
2260 parseerror(parser, "expected variable definition");
2264 typevar = parse_type(parser, basetype, &isfunc);
2275 ve[0].name = ve[1].name = ve[2].name = NULL;
2276 ve[0].var = ve[1].var = ve[2].var = NULL;
2278 ctx = parser_ctx(parser);
2279 var = ast_value_copy(typevar);
2283 parseerror(parser, "failed to create variable");
2288 if (parser->tok != TOKEN_IDENT) {
2289 parseerror(parser, "expected variable name");
2295 if (!strcmp(parser_tokval(parser), "end_sys_globals"))
2296 parser->crc_globals = parser->globals_count;
2297 else if (!strcmp(parser_tokval(parser), "end_sys_fields"))
2298 parser->crc_fields = parser->fields_count;
2302 if (!localblock && (olddecl = parser_find_global(parser, parser_tokval(parser)))) {
2303 parseerror(parser, "global `%s` already declared here: %s:%i",
2304 parser_tokval(parser), ast_ctx(olddecl).file, (int)ast_ctx(olddecl).line);
2310 olddecl = parser_find_local(parser, parser_tokval(parser), parser->blocklocal, &isparam);
2311 if (opts_standard == COMPILER_GMQCC)
2316 parseerror(parser, "local `%s` already declared here: %s:%i",
2317 parser_tokval(parser), ast_ctx(olddecl).file, (int)ast_ctx(olddecl).line);
2323 if( (!isparam && olddecl) ||
2324 (olddecl = parser_find_local(parser, parser_tokval(parser), 0, &isparam))
2327 if (parsewarning(parser, WARN_LOCAL_SHADOWS,
2328 "local `%s` is shadowing a parameter", parser_tokval(parser)))
2330 parseerror(parser, "local `%s` already declared here: %s:%i",
2331 parser_tokval(parser), ast_ctx(olddecl).file, (int)ast_ctx(olddecl).line);
2341 ast_value_delete(var);
2344 parsewarning(parser, WARN_LOCAL_SHADOWS,
2345 "a parameter is shadowing local `%s`", parser_tokval(parser)))
2352 parseerror(parser, "local `%s` already declared here: %s:%i",
2353 parser_tokval(parser), ast_ctx(olddecl).file, (int)ast_ctx(olddecl).line);
2363 if (!ast_value_set_name(var, parser_tokval(parser))) {
2364 parseerror(parser, "failed to set variable name\n");
2370 /* a function was defined */
2372 ast_value *proto = NULL;
2376 olddecl = parser_find_global(parser, parser_tokval(parser));
2378 olddecl = parser_find_local(parser, parser_tokval(parser), parser->blocklocal, &dummy);
2381 /* we had a prototype */
2382 if (!ast_istype(olddecl, ast_value)) {
2386 parseerror(parser, "cannot declare a function with the same name as a vector's member: %s",
2387 parser_tokval(parser));
2392 proto = (ast_value*)olddecl;
2395 /* turn var into a value of TYPE_FUNCTION, with the old var
2398 fval = ast_value_new(ctx, var->name, TYPE_FUNCTION);
2404 fval->expression.next = (ast_expression*)var;
2405 MEM_VECTOR_MOVE(&var->expression, params, &fval->expression, params);
2406 fval->expression.variadic = var->expression.variadic;
2409 /* we compare the type late here, but it's easier than
2410 * messing with the parameter-vector etc. earlier
2414 if (!ast_compare_type((ast_expression*)proto, (ast_expression*)fval)) {
2415 parseerror(parser, "conflicting types for `%s`, previous declaration was here: %s:%i",
2417 ast_ctx(proto).file, ast_ctx(proto).line);
2418 ast_value_delete(fval);
2422 /* copy over the parameter names */
2423 for (param = 0; param < fval->expression.params_count; ++param)
2424 ast_value_set_name(proto->expression.params[param], fval->expression.params[param]->name);
2425 /* copy the new context */
2426 ast_ctx(proto) = ast_ctx(fval);
2428 /* now ditch the rest of the new data */
2429 ast_value_delete(fval);
2438 varent.name = util_strdup(var->name);
2439 varent.var = (ast_expression*)var;
2442 if (!(retval = parser_t_globals_add(parser, varent)))
2445 if (!(retval = parser_t_locals_add(parser, varent)))
2447 if (!(retval = ast_block_locals_add(localblock, var))) {
2448 parser->locals_count--;
2453 if (var->expression.vtype == TYPE_VECTOR)
2456 if (!create_vector_members(parser, var, ve)) {
2462 for (e = 0; e < 3; ++e) {
2463 if (!(retval = parser_t_globals_add(parser, ve[e])))
2467 parser->globals_count -= e+1;
2471 for (e = 0; e < 3; ++e) {
2472 if (!(retval = parser_t_locals_add(parser, ve[e])))
2474 if (!(retval = ast_block_collect(localblock, ve[e].var)))
2476 ve[e].var = NULL; /* from here it's being collected in the block */
2479 parser->locals_count -= e+1;
2480 localblock->locals_count--;
2484 ve[0].name = ve[1].name = ve[2].name = NULL;
2485 ve[0].var = ve[1].var = ve[2].var = NULL;
2492 if (!(retval = parser_next(parser)))
2495 if (parser->tok == ';') {
2496 ast_value_delete(typevar);
2497 return parser_next(parser);
2500 if (parser->tok == ',') {
2502 if (!(retval = parser_next(parser)))
2507 /* NOTE: only 'typevar' needs to be deleted from here on, so 'cleanup' won't be used
2508 * to avoid having too many gotos
2510 if (localblock && opts_standard == COMPILER_QCC) {
2511 if (parsewarning(parser, WARN_LOCAL_CONSTANTS,
2512 "initializing expression turns variable `%s` into a constant in this standard",
2515 ast_value_delete(typevar);
2520 if (parser->tok != '=') {
2521 if (opts_standard == COMPILER_QCC)
2522 parseerror(parser, "missing semicolon");
2524 parseerror(parser, "missing semicolon or initializer");
2525 ast_value_delete(typevar);
2529 if (!parser_next(parser)) {
2530 ast_value_delete(typevar);
2534 if (parser->tok == '#') {
2538 parseerror(parser, "cannot declare builtins within functions");
2539 ast_value_delete(typevar);
2543 parseerror(parser, "unexpected builtin number, '%s' is not a function", var->name);
2544 ast_value_delete(typevar);
2547 if (!parser_next(parser)) {
2548 parseerror(parser, "expected builtin number");
2549 ast_value_delete(typevar);
2552 if (parser->tok != TOKEN_INTCONST) {
2553 parseerror(parser, "builtin number must be an integer constant");
2554 ast_value_delete(typevar);
2557 if (parser_token(parser)->constval.i <= 0) {
2558 parseerror(parser, "builtin number must be positive integer greater than zero");
2559 ast_value_delete(typevar);
2563 func = ast_function_new(ast_ctx(var), var->name, var);
2565 parseerror(parser, "failed to allocate function for `%s`", var->name);
2566 ast_value_delete(typevar);
2569 if (!parser_t_functions_add(parser, func)) {
2570 parseerror(parser, "failed to allocate slot for function `%s`", var->name);
2571 ast_function_delete(func);
2572 var->constval.vfunc = NULL;
2573 ast_value_delete(typevar);
2577 func->builtin = -parser_token(parser)->constval.i;
2579 if (!parser_next(parser)) {
2580 ast_value_delete(typevar);
2584 else if (parser->tok == '{' || parser->tok == '[')
2586 ast_value_delete(typevar);
2588 parseerror(parser, "cannot declare functions within functions");
2592 if (!parse_function_body(parser, var)) {
2597 ast_expression *cexp;
2600 cexp = parse_expression_leave(parser, true);
2602 ast_value_delete(typevar);
2606 cval = (ast_value*)cexp;
2607 if (!ast_istype(cval, ast_value) || !cval->isconst)
2608 parseerror(parser, "cannot initialize a global constant variable with a non-constant expression");
2611 var->isconst = true;
2612 if (cval->expression.vtype == TYPE_STRING)
2613 var->constval.vstring = parser_strdup(cval->constval.vstring);
2615 memcpy(&var->constval, &cval->constval, sizeof(var->constval));
2620 if (parser->tok == ',') {
2625 if (parser->tok != ';') {
2626 parseerror(parser, "missing semicolon");
2627 ast_value_delete(typevar);
2631 (void)parser_next(parser);
2633 ast_value_delete(typevar);
2638 ast_delete(typevar);
2639 if (var && cleanvar) ast_delete(var);
2640 if (varent.name) mem_d(varent.name);
2641 if (ve[0].name) mem_d(ve[0].name);
2642 if (ve[1].name) mem_d(ve[1].name);
2643 if (ve[2].name) mem_d(ve[2].name);
2644 if (ve[0].var) mem_d(ve[0].var);
2645 if (ve[1].var) mem_d(ve[1].var);
2646 if (ve[2].var) mem_d(ve[2].var);
2651 static bool parser_global_statement(parser_t *parser)
2653 if (parser->tok == TOKEN_TYPENAME)
2655 return parse_variable(parser, NULL);
2657 else if (parser->tok == TOKEN_KEYWORD)
2659 /* handle 'var' and 'const' */
2662 else if (parser->tok == '.')
2667 ast_expression *oldex;
2668 bool isfunc = false;
2670 lex_ctx ctx = parser_ctx(parser);
2673 /* entity-member declaration */
2674 if (!parser_next(parser) || parser->tok != TOKEN_TYPENAME) {
2675 parseerror(parser, "expected member variable definition");
2679 /* remember the base/return type */
2680 basetype = parser_token(parser)->constval.t;
2682 /* parse into the declaration */
2683 if (!parser_next(parser)) {
2684 parseerror(parser, "expected field definition");
2688 /* parse the field type fully */
2689 typevar = var = parse_type(parser, basetype, &isfunc);
2694 var = ast_value_copy(typevar);
2695 /* now the field name */
2696 if (parser->tok != TOKEN_IDENT) {
2697 parseerror(parser, "expected field name");
2702 /* check for an existing field
2703 * in original qc we also have to check for an existing
2704 * global named like the field
2706 if (opts_standard == COMPILER_QCC) {
2707 if (parser_find_global(parser, parser_tokval(parser))) {
2708 parseerror(parser, "cannot declare a field and a global of the same name with -std=qcc");
2716 fval = ast_value_new(ctx, var->name, TYPE_FUNCTION);
2718 ast_value_delete(var);
2721 fval->expression.next = (ast_expression*)var;
2722 MEM_VECTOR_MOVE(&var->expression, params, &fval->expression, params);
2723 fval->expression.variadic = var->expression.variadic;
2727 if (!strcmp(parser_tokval(parser), "end_sys_fields")) {
2728 if (parsewarning(parser, WARN_END_SYS_FIELDS, "by convention end_sys_fields should be declared as global, rather than a field")) {
2729 ast_value_delete(var);
2734 /* turn it into a field */
2735 fld = ast_value_new(ctx, parser_tokval(parser), TYPE_FIELD);
2736 fld->expression.next = (ast_expression*)var;
2738 if ( (oldex = parser_find_field(parser, parser_tokval(parser)))) {
2739 if (ast_istype(oldex, ast_member)) {
2740 parseerror(parser, "cannot declare a field with the same name as a vector component, component %s has been declared here: %s:%i",
2741 parser_tokval(parser), ast_ctx(oldex).file, (int)ast_ctx(oldex).line);
2745 if (!ast_istype(oldex, ast_value)) {
2746 /* not possible / sanity check */
2747 parseerror(parser, "internal error: %s is not an ast_value", parser_tokval(parser));
2752 if (!ast_compare_type(oldex, (ast_expression*)fld)) {
2753 parseerror(parser, "field %s has previously been declared with a different type here: %s:%i",
2754 parser_tokval(parser), ast_ctx(oldex).file, (int)ast_ctx(oldex).line);
2758 if (parsewarning(parser, WARN_FIELD_REDECLARED, "field `%s` has already been declared here: %s:%i",
2759 parser_tokval(parser), ast_ctx(oldex).file, (int)ast_ctx(oldex).line))
2770 varent.var = (ast_expression*)fld;
2771 varent.name = util_strdup(fld->name);
2772 (void)!parser_t_fields_add(parser, varent);
2774 if (var->expression.vtype == TYPE_VECTOR)
2776 /* create _x, _y and _z fields as well */
2778 if (!create_vector_members(parser, fld, ve)) {
2782 (void)!parser_t_fields_add(parser, ve[0]);
2783 (void)!parser_t_fields_add(parser, ve[1]);
2784 (void)!parser_t_fields_add(parser, ve[2]);
2788 if (!parser_next(parser)) {
2789 parseerror(parser, "expected semicolon or another field name");
2792 if (parser->tok == ';')
2794 if (parser->tok != ',' || !parser_next(parser)) {
2795 parseerror(parser, "expected semicolon or another field name");
2799 ast_delete(typevar);
2801 /* skip the semicolon */
2802 if (!parser_next(parser))
2803 return parser->tok == TOKEN_EOF;
2807 else if (parser->tok == '$')
2809 if (!parser_next(parser)) {
2810 parseerror(parser, "parse error");
2816 parseerror(parser, "unexpected token: %s", parser->lex->tok.value);
2822 static parser_t *parser;
2826 parser = (parser_t*)mem_a(sizeof(parser_t));
2830 memset(parser, 0, sizeof(*parser));
2834 bool parser_compile(const char *filename)
2836 parser->lex = lex_open(filename);
2838 printf("failed to open file \"%s\"\n", filename);
2842 /* initial lexer/parser state */
2843 parser->lex->flags.noops = true;
2845 if (parser_next(parser))
2847 while (parser->tok != TOKEN_EOF && parser->tok < TOKEN_ERROR)
2849 if (!parser_global_statement(parser)) {
2850 if (parser->tok == TOKEN_EOF)
2851 parseerror(parser, "unexpected eof");
2852 else if (!parser->errors)
2853 parseerror(parser, "parse error");
2854 lex_close(parser->lex);
2860 parseerror(parser, "parse error");
2861 lex_close(parser->lex);
2866 lex_close(parser->lex);
2869 return !parser->errors;
2872 void parser_cleanup()
2875 for (i = 0; i < parser->functions_count; ++i) {
2876 ast_delete(parser->functions[i]);
2878 for (i = 0; i < parser->imm_vector_count; ++i) {
2879 ast_delete(parser->imm_vector[i]);
2881 for (i = 0; i < parser->imm_string_count; ++i) {
2882 ast_delete(parser->imm_string[i]);
2884 for (i = 0; i < parser->imm_float_count; ++i) {
2885 ast_delete(parser->imm_float[i]);
2887 for (i = 0; i < parser->fields_count; ++i) {
2888 ast_delete(parser->fields[i].var);
2889 mem_d(parser->fields[i].name);
2891 for (i = 0; i < parser->globals_count; ++i) {
2892 ast_delete(parser->globals[i].var);
2893 mem_d(parser->globals[i].name);
2895 MEM_VECTOR_CLEAR(parser, functions);
2896 MEM_VECTOR_CLEAR(parser, imm_vector);
2897 MEM_VECTOR_CLEAR(parser, imm_string);
2898 MEM_VECTOR_CLEAR(parser, imm_float);
2899 MEM_VECTOR_CLEAR(parser, globals);
2900 MEM_VECTOR_CLEAR(parser, fields);
2901 MEM_VECTOR_CLEAR(parser, locals);
2906 static uint16_t progdefs_crc_sum(uint16_t old, const char *str)
2908 return util_crc16(old, str, strlen(str));
2911 static void progdefs_crc_file(const char *str)
2913 /* write to progdefs.h here */
2916 static uint16_t progdefs_crc_both(uint16_t old, const char *str)
2918 old = progdefs_crc_sum(old, str);
2919 progdefs_crc_file(str);
2923 static void generate_checksum(parser_t *parser)
2925 uint16_t crc = 0xFFFF;
2928 crc = progdefs_crc_both(crc, "\n/* file generated by qcc, do not modify */\n\ntypedef struct\n{");
2929 crc = progdefs_crc_sum(crc, "\tint\tpad[28];\n");
2931 progdefs_crc_file("\tint\tpad;\n");
2932 progdefs_crc_file("\tint\tofs_return[3];\n");
2933 progdefs_crc_file("\tint\tofs_parm0[3];\n");
2934 progdefs_crc_file("\tint\tofs_parm1[3];\n");
2935 progdefs_crc_file("\tint\tofs_parm2[3];\n");
2936 progdefs_crc_file("\tint\tofs_parm3[3];\n");
2937 progdefs_crc_file("\tint\tofs_parm4[3];\n");
2938 progdefs_crc_file("\tint\tofs_parm5[3];\n");
2939 progdefs_crc_file("\tint\tofs_parm6[3];\n");
2940 progdefs_crc_file("\tint\tofs_parm7[3];\n");
2942 for (i = 0; i < parser->crc_globals; ++i) {
2943 if (!ast_istype(parser->globals[i].var, ast_value))
2945 switch (parser->globals[i].var->expression.vtype) {
2946 case TYPE_FLOAT: crc = progdefs_crc_both(crc, "\tfloat\t"); break;
2947 case TYPE_VECTOR: crc = progdefs_crc_both(crc, "\tvec3_t\t"); break;
2948 case TYPE_STRING: crc = progdefs_crc_both(crc, "\tstring_t\t"); break;
2949 case TYPE_FUNCTION: crc = progdefs_crc_both(crc, "\tfunc_t\t"); break;
2951 crc = progdefs_crc_both(crc, "\tint\t");
2954 crc = progdefs_crc_both(crc, parser->globals[i].name);
2955 crc = progdefs_crc_both(crc, ";\n");
2957 crc = progdefs_crc_both(crc, "} globalvars_t;\n\ntypedef struct\n{\n");
2958 for (i = 0; i < parser->crc_fields; ++i) {
2959 if (!ast_istype(parser->fields[i].var, ast_value))
2961 switch (parser->fields[i].var->expression.next->expression.vtype) {
2962 case TYPE_FLOAT: crc = progdefs_crc_both(crc, "\tfloat\t"); break;
2963 case TYPE_VECTOR: crc = progdefs_crc_both(crc, "\tvec3_t\t"); break;
2964 case TYPE_STRING: crc = progdefs_crc_both(crc, "\tstring_t\t"); break;
2965 case TYPE_FUNCTION: crc = progdefs_crc_both(crc, "\tfunc_t\t"); break;
2967 crc = progdefs_crc_both(crc, "\tint\t");
2970 crc = progdefs_crc_both(crc, parser->fields[i].name);
2971 crc = progdefs_crc_both(crc, ";\n");
2973 crc = progdefs_crc_both(crc, "} entvars_t;\n\n");
2978 bool parser_finish(const char *output)
2984 if (!parser->errors)
2986 ir = ir_builder_new("gmqcc_out");
2988 printf("failed to allocate builder\n");
2992 for (i = 0; i < parser->fields_count; ++i) {
2995 if (!ast_istype(parser->fields[i].var, ast_value))
2997 field = (ast_value*)parser->fields[i].var;
2998 isconst = field->isconst;
2999 field->isconst = false;
3000 if (!ast_global_codegen((ast_value*)field, ir)) {
3001 printf("failed to generate field %s\n", field->name);
3002 ir_builder_delete(ir);
3007 ast_expression *subtype;
3008 field->isconst = true;
3009 subtype = field->expression.next;
3010 ifld = ir_builder_create_field(ir, field->name, subtype->expression.vtype);
3011 if (subtype->expression.vtype == TYPE_FIELD)
3012 ifld->fieldtype = subtype->expression.next->expression.vtype;
3013 else if (subtype->expression.vtype == TYPE_FUNCTION)
3014 ifld->outtype = subtype->expression.next->expression.vtype;
3015 (void)!ir_value_set_field(field->ir_v, ifld);
3018 for (i = 0; i < parser->globals_count; ++i) {
3020 if (!ast_istype(parser->globals[i].var, ast_value))
3022 asvalue = (ast_value*)(parser->globals[i].var);
3023 if (!asvalue->uses && !asvalue->isconst && asvalue->expression.vtype != TYPE_FUNCTION) {
3024 if (strcmp(asvalue->name, "end_sys_globals") &&
3025 strcmp(asvalue->name, "end_sys_fields"))
3027 retval = retval && !genwarning(ast_ctx(asvalue), WARN_UNUSED_VARIABLE,
3028 "unused global: `%s`", asvalue->name);
3031 if (!ast_global_codegen(asvalue, ir)) {
3032 printf("failed to generate global %s\n", parser->globals[i].name);
3033 ir_builder_delete(ir);
3037 for (i = 0; i < parser->imm_float_count; ++i) {
3038 if (!ast_global_codegen(parser->imm_float[i], ir)) {
3039 printf("failed to generate global %s\n", parser->imm_float[i]->name);
3040 ir_builder_delete(ir);
3044 for (i = 0; i < parser->imm_string_count; ++i) {
3045 if (!ast_global_codegen(parser->imm_string[i], ir)) {
3046 printf("failed to generate global %s\n", parser->imm_string[i]->name);
3047 ir_builder_delete(ir);
3051 for (i = 0; i < parser->imm_vector_count; ++i) {
3052 if (!ast_global_codegen(parser->imm_vector[i], ir)) {
3053 printf("failed to generate global %s\n", parser->imm_vector[i]->name);
3054 ir_builder_delete(ir);
3058 for (i = 0; i < parser->functions_count; ++i) {
3059 if (!ast_function_codegen(parser->functions[i], ir)) {
3060 printf("failed to generate function %s\n", parser->functions[i]->name);
3061 ir_builder_delete(ir);
3064 if (!ir_function_finalize(parser->functions[i]->ir_func)) {
3065 printf("failed to finalize function %s\n", parser->functions[i]->name);
3066 ir_builder_delete(ir);
3073 ir_builder_dump(ir, printf);
3075 generate_checksum(parser);
3077 if (!ir_builder_generate(ir, output)) {
3078 printf("*** failed to generate output file\n");
3079 ir_builder_delete(ir);
3084 ir_builder_delete(ir);
3088 printf("*** there were compile errors\n");