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);
311 size_t etype; /* 0 = expression, others are operators */
315 ast_block *block; /* for commas and function calls */
320 MEM_VECTOR_MAKE(sy_elem, out);
321 MEM_VECTOR_MAKE(sy_elem, ops);
323 MEM_VEC_FUNCTIONS(shunt, sy_elem, out)
324 MEM_VEC_FUNCTIONS(shunt, sy_elem, ops)
326 static sy_elem syexp(lex_ctx ctx, ast_expression *v) {
337 static sy_elem syblock(lex_ctx ctx, ast_block *v) {
341 e.out = (ast_expression*)v;
348 static sy_elem syop(lex_ctx ctx, const oper_info *op) {
350 e.etype = 1 + (op - operators);
359 static sy_elem syparen(lex_ctx ctx, int p, size_t off) {
371 # define DEBUGSHUNTDO(x) x
373 # define DEBUGSHUNTDO(x)
376 static bool parser_sy_pop(parser_t *parser, shunt *sy)
380 ast_expression *out = NULL;
381 ast_expression *exprs[3];
382 ast_block *blocks[3];
383 ast_value *asvalue[3];
385 qcint generated_op = 0;
387 if (!sy->ops_count) {
388 parseerror(parser, "internal error: missing operator");
392 if (sy->ops[sy->ops_count-1].paren) {
393 parseerror(parser, "unmatched parenthesis");
397 op = &operators[sy->ops[sy->ops_count-1].etype - 1];
398 ctx = sy->ops[sy->ops_count-1].ctx;
400 DEBUGSHUNTDO(printf("apply %s\n", op->op));
402 if (sy->out_count < op->operands) {
403 parseerror(parser, "internal error: not enough operands: %i (operator %s (%i))", sy->out_count,
404 op->op, (int)op->id);
410 sy->out_count -= op->operands;
411 for (i = 0; i < op->operands; ++i) {
412 exprs[i] = sy->out[sy->out_count+i].out;
413 blocks[i] = sy->out[sy->out_count+i].block;
414 asvalue[i] = (ast_value*)exprs[i];
417 if (blocks[0] && !blocks[0]->exprs_count && op->id != opid1(',')) {
418 parseerror(parser, "internal error: operator cannot be applied on empty blocks");
422 #define NotSameType(T) \
423 (exprs[0]->expression.vtype != exprs[1]->expression.vtype || \
424 exprs[0]->expression.vtype != T)
425 #define CanConstFold1(A) \
426 (ast_istype((A), ast_value) && ((ast_value*)(A))->isconst)
427 #define CanConstFold(A, B) \
428 (CanConstFold1(A) && CanConstFold1(B))
429 #define ConstV(i) (asvalue[(i)]->constval.vvec)
430 #define ConstF(i) (asvalue[(i)]->constval.vfloat)
431 #define ConstS(i) (asvalue[(i)]->constval.vstring)
435 parseerror(parser, "internal error: unhandled operator: %s (%i)", op->op, (int)op->id);
439 if (exprs[0]->expression.vtype == TYPE_ENTITY) {
440 if (exprs[1]->expression.vtype != TYPE_FIELD) {
441 parseerror(parser, "type error: right hand of member-operand should be an entity-field");
444 out = (ast_expression*)ast_entfield_new(ctx, exprs[0], exprs[1]);
446 else if (exprs[0]->expression.vtype == TYPE_VECTOR) {
447 parseerror(parser, "internal error: vector access is not supposed to be handled at this point");
451 parseerror(parser, "type error: member-of operator on something that is not an entity or vector");
458 if (!ast_block_exprs_add(blocks[0], exprs[1]))
461 blocks[0] = ast_block_new(ctx);
462 if (!ast_block_exprs_add(blocks[0], exprs[0]) ||
463 !ast_block_exprs_add(blocks[0], exprs[1]))
468 if (!ast_block_set_type(blocks[0], exprs[1]))
471 sy->out[sy->out_count++] = syblock(ctx, blocks[0]);
475 switch (exprs[0]->expression.vtype) {
477 if (CanConstFold1(exprs[0]))
478 out = (ast_expression*)parser_const_float(parser, -ConstF(0));
480 out = (ast_expression*)ast_binary_new(ctx, INSTR_SUB_F,
481 (ast_expression*)parser_const_float_0(parser),
485 if (CanConstFold1(exprs[0]))
486 out = (ast_expression*)parser_const_vector_f(parser,
487 -ConstV(0).x, -ConstV(0).y, -ConstV(0).z);
489 out = (ast_expression*)ast_binary_new(ctx, INSTR_SUB_V,
490 (ast_expression*)parser_const_vector_0(parser),
494 parseerror(parser, "invalid types used in expression: cannot negate type %s",
495 type_name[exprs[0]->expression.vtype]);
501 switch (exprs[0]->expression.vtype) {
503 if (CanConstFold1(exprs[0]))
504 out = (ast_expression*)parser_const_float(parser, !ConstF(0));
506 out = (ast_expression*)ast_unary_new(ctx, INSTR_NOT_F, exprs[0]);
509 if (CanConstFold1(exprs[0]))
510 out = (ast_expression*)parser_const_float(parser,
511 (!ConstV(0).x && !ConstV(0).y && !ConstV(0).z));
513 out = (ast_expression*)ast_unary_new(ctx, INSTR_NOT_V, exprs[0]);
516 if (CanConstFold1(exprs[0]))
517 out = (ast_expression*)parser_const_float(parser, !ConstS(0) || !*ConstS(0));
519 out = (ast_expression*)ast_unary_new(ctx, INSTR_NOT_S, exprs[0]);
521 /* we don't constant-fold NOT for these types */
523 out = (ast_expression*)ast_unary_new(ctx, INSTR_NOT_ENT, exprs[0]);
526 out = (ast_expression*)ast_unary_new(ctx, INSTR_NOT_FNC, exprs[0]);
529 parseerror(parser, "invalid types used in expression: cannot logically negate type %s",
530 type_name[exprs[0]->expression.vtype]);
536 if (exprs[0]->expression.vtype != exprs[1]->expression.vtype ||
537 (exprs[0]->expression.vtype != TYPE_VECTOR && exprs[0]->expression.vtype != TYPE_FLOAT) )
539 parseerror(parser, "invalid types used in expression: cannot add type %s and %s",
540 type_name[exprs[0]->expression.vtype],
541 type_name[exprs[1]->expression.vtype]);
544 switch (exprs[0]->expression.vtype) {
546 if (CanConstFold(exprs[0], exprs[1]))
548 out = (ast_expression*)parser_const_float(parser, ConstF(0) + ConstF(1));
551 out = (ast_expression*)ast_binary_new(ctx, INSTR_ADD_F, exprs[0], exprs[1]);
554 if (CanConstFold(exprs[0], exprs[1]))
555 out = (ast_expression*)parser_const_vector(parser, vec3_add(ConstV(0), ConstV(1)));
557 out = (ast_expression*)ast_binary_new(ctx, INSTR_ADD_V, exprs[0], exprs[1]);
560 parseerror(parser, "invalid types used in expression: cannot add type %s and %s",
561 type_name[exprs[0]->expression.vtype],
562 type_name[exprs[1]->expression.vtype]);
567 if (exprs[0]->expression.vtype != exprs[1]->expression.vtype ||
568 (exprs[0]->expression.vtype != TYPE_VECTOR && exprs[0]->expression.vtype != TYPE_FLOAT) )
570 parseerror(parser, "invalid types used in expression: cannot subtract type %s from %s",
571 type_name[exprs[1]->expression.vtype],
572 type_name[exprs[0]->expression.vtype]);
575 switch (exprs[0]->expression.vtype) {
577 if (CanConstFold(exprs[0], exprs[1]))
578 out = (ast_expression*)parser_const_float(parser, ConstF(0) - ConstF(1));
580 out = (ast_expression*)ast_binary_new(ctx, INSTR_SUB_F, exprs[0], exprs[1]);
583 if (CanConstFold(exprs[0], exprs[1]))
584 out = (ast_expression*)parser_const_vector(parser, vec3_sub(ConstV(0), ConstV(1)));
586 out = (ast_expression*)ast_binary_new(ctx, INSTR_SUB_V, exprs[0], exprs[1]);
589 parseerror(parser, "invalid types used in expression: cannot subtract type %s from %s",
590 type_name[exprs[1]->expression.vtype],
591 type_name[exprs[0]->expression.vtype]);
596 if (exprs[0]->expression.vtype != exprs[1]->expression.vtype &&
597 exprs[0]->expression.vtype != TYPE_VECTOR &&
598 exprs[0]->expression.vtype != TYPE_FLOAT &&
599 exprs[1]->expression.vtype != TYPE_VECTOR &&
600 exprs[1]->expression.vtype != TYPE_FLOAT)
602 parseerror(parser, "invalid types used in expression: cannot multiply types %s and %s",
603 type_name[exprs[1]->expression.vtype],
604 type_name[exprs[0]->expression.vtype]);
607 switch (exprs[0]->expression.vtype) {
609 if (exprs[1]->expression.vtype == TYPE_VECTOR)
611 if (CanConstFold(exprs[0], exprs[1]))
612 out = (ast_expression*)parser_const_vector(parser, vec3_mulvf(ConstV(1), ConstF(0)));
614 out = (ast_expression*)ast_binary_new(ctx, INSTR_MUL_FV, exprs[0], exprs[1]);
618 if (CanConstFold(exprs[0], exprs[1]))
619 out = (ast_expression*)parser_const_float(parser, ConstF(0) * ConstF(1));
621 out = (ast_expression*)ast_binary_new(ctx, INSTR_MUL_F, exprs[0], exprs[1]);
625 if (exprs[1]->expression.vtype == TYPE_FLOAT)
627 if (CanConstFold(exprs[0], exprs[1]))
628 out = (ast_expression*)parser_const_vector(parser, vec3_mulvf(ConstV(0), ConstF(1)));
630 out = (ast_expression*)ast_binary_new(ctx, INSTR_MUL_VF, exprs[0], exprs[1]);
634 if (CanConstFold(exprs[0], exprs[1]))
635 out = (ast_expression*)parser_const_float(parser, vec3_mulvv(ConstV(0), ConstV(1)));
637 out = (ast_expression*)ast_binary_new(ctx, INSTR_MUL_V, exprs[0], exprs[1]);
641 parseerror(parser, "invalid types used in expression: cannot multiply types %s and %s",
642 type_name[exprs[1]->expression.vtype],
643 type_name[exprs[0]->expression.vtype]);
648 if (NotSameType(TYPE_FLOAT)) {
649 parseerror(parser, "invalid types used in expression: cannot divide types %s and %s",
650 type_name[exprs[0]->expression.vtype],
651 type_name[exprs[1]->expression.vtype]);
654 if (CanConstFold(exprs[0], exprs[1]))
655 out = (ast_expression*)parser_const_float(parser, ConstF(0) / ConstF(1));
657 out = (ast_expression*)ast_binary_new(ctx, INSTR_DIV_F, exprs[0], exprs[1]);
661 parseerror(parser, "qc does not have a modulo operator");
665 if (NotSameType(TYPE_FLOAT)) {
666 parseerror(parser, "invalid types used in expression: cannot perform bit operations between types %s and %s",
667 type_name[exprs[0]->expression.vtype],
668 type_name[exprs[1]->expression.vtype]);
671 if (CanConstFold(exprs[0], exprs[1]))
672 out = (ast_expression*)parser_const_float(parser,
673 (op->id == opid1('|') ? (float)( ((qcint)ConstF(0)) | ((qcint)ConstF(1)) ) :
674 (float)( ((qcint)ConstF(0)) & ((qcint)ConstF(1)) ) ));
676 out = (ast_expression*)ast_binary_new(ctx,
677 (op->id == opid1('|') ? INSTR_BITOR : INSTR_BITAND),
681 parseerror(parser, "TODO: bitxor");
686 case opid3('<','<','='):
687 case opid3('>','>','='):
688 parseerror(parser, "TODO: shifts");
692 generated_op += 1; /* INSTR_OR */
694 generated_op += INSTR_AND;
695 if (NotSameType(TYPE_FLOAT)) {
696 parseerror(parser, "invalid types used in expression: cannot perform logical operations between types %s and %s",
697 type_name[exprs[0]->expression.vtype],
698 type_name[exprs[1]->expression.vtype]);
699 parseerror(parser, "TODO: logical ops for arbitrary types using INSTR_NOT");
700 parseerror(parser, "TODO: optional early out");
703 if (opts_standard == COMPILER_GMQCC)
704 printf("TODO: early out logic\n");
705 if (CanConstFold(exprs[0], exprs[1]))
706 out = (ast_expression*)parser_const_float(parser,
707 (generated_op == INSTR_OR ? (ConstF(0) || ConstF(1)) : (ConstF(0) && ConstF(1))));
709 out = (ast_expression*)ast_binary_new(ctx, generated_op, exprs[0], exprs[1]);
713 generated_op += 1; /* INSTR_GT */
715 generated_op += 1; /* INSTR_LT */
716 case opid2('>', '='):
717 generated_op += 1; /* INSTR_GE */
718 case opid2('<', '='):
719 generated_op += INSTR_LE;
720 if (NotSameType(TYPE_FLOAT)) {
721 parseerror(parser, "invalid types used in expression: cannot perform comparison between types %s and %s",
722 type_name[exprs[0]->expression.vtype],
723 type_name[exprs[1]->expression.vtype]);
726 out = (ast_expression*)ast_binary_new(ctx, generated_op, exprs[0], exprs[1]);
728 case opid2('!', '='):
729 if (exprs[0]->expression.vtype != exprs[1]->expression.vtype) {
730 parseerror(parser, "invalid types used in expression: cannot perform comparison between types %s and %s",
731 type_name[exprs[0]->expression.vtype],
732 type_name[exprs[1]->expression.vtype]);
735 out = (ast_expression*)ast_binary_new(ctx, type_ne_instr[exprs[0]->expression.vtype], exprs[0], exprs[1]);
737 case opid2('=', '='):
738 if (exprs[0]->expression.vtype != exprs[1]->expression.vtype) {
739 parseerror(parser, "invalid types used in expression: cannot perform comparison between types %s and %s",
740 type_name[exprs[0]->expression.vtype],
741 type_name[exprs[1]->expression.vtype]);
744 out = (ast_expression*)ast_binary_new(ctx, type_eq_instr[exprs[0]->expression.vtype], exprs[0], exprs[1]);
748 if (ast_istype(exprs[0], ast_entfield)) {
749 ast_expression *field = ((ast_entfield*)exprs[0])->field;
750 assignop = type_storep_instr[exprs[0]->expression.vtype];
751 if (!ast_compare_type(field->expression.next, exprs[1])) {
754 ast_type_to_string(field->expression.next, ty1, sizeof(ty1));
755 ast_type_to_string(exprs[1], ty2, sizeof(ty2));
756 if (opts_standard == COMPILER_QCC &&
757 field->expression.next->expression.vtype == TYPE_FUNCTION &&
758 exprs[1]->expression.vtype == TYPE_FUNCTION)
760 if (parsewarning(parser, WARN_ASSIGN_FUNCTION_TYPES,
761 "invalid types in assignment: cannot assign %s to %s", ty2, ty1))
767 parseerror(parser, "invalid types in assignment: cannot assign %s to %s", ty2, ty1);
772 assignop = type_store_instr[exprs[0]->expression.vtype];
773 if (!ast_compare_type(exprs[0], exprs[1])) {
776 ast_type_to_string(exprs[0], ty1, sizeof(ty1));
777 ast_type_to_string(exprs[1], ty2, sizeof(ty2));
778 if (opts_standard == COMPILER_QCC &&
779 exprs[0]->expression.vtype == TYPE_FUNCTION &&
780 exprs[1]->expression.vtype == TYPE_FUNCTION)
782 if (parsewarning(parser, WARN_ASSIGN_FUNCTION_TYPES,
783 "invalid types in assignment: cannot assign %s to %s", ty2, ty1))
789 parseerror(parser, "invalid types in assignment: cannot assign %s to %s", ty2, ty1);
792 out = (ast_expression*)ast_store_new(ctx, assignop, exprs[0], exprs[1]);
796 if (exprs[0]->expression.vtype != exprs[1]->expression.vtype ||
797 (exprs[0]->expression.vtype != TYPE_VECTOR && exprs[0]->expression.vtype != TYPE_FLOAT) )
799 parseerror(parser, "invalid types used in expression: cannot add or subtract type %s and %s",
800 type_name[exprs[0]->expression.vtype],
801 type_name[exprs[1]->expression.vtype]);
804 if (ast_istype(exprs[0], ast_entfield))
805 assignop = type_storep_instr[exprs[0]->expression.vtype];
807 assignop = type_store_instr[exprs[0]->expression.vtype];
808 switch (exprs[0]->expression.vtype) {
810 out = (ast_expression*)ast_binstore_new(ctx, assignop,
811 (op->id == opid2('+','=') ? INSTR_ADD_F : INSTR_SUB_F),
815 out = (ast_expression*)ast_binstore_new(ctx, assignop,
816 (op->id == opid2('+','=') ? INSTR_ADD_V : INSTR_SUB_V),
820 parseerror(parser, "invalid types used in expression: cannot add or subtract type %s and %s",
821 type_name[exprs[0]->expression.vtype],
822 type_name[exprs[1]->expression.vtype]);
830 parseerror(parser, "failed to apply operand %s", op->op);
834 DEBUGSHUNTDO(printf("applied %s\n", op->op));
835 sy->out[sy->out_count++] = syexp(ctx, out);
839 static bool parser_close_call(parser_t *parser, shunt *sy)
841 /* was a function call */
849 fid = sy->ops[sy->ops_count].off;
851 /* out[fid] is the function
852 * everything above is parameters...
854 * 1 params = ast_expression
858 if (sy->out_count < 1 || sy->out_count <= fid) {
859 parseerror(parser, "internal error: function call needs function and parameter list...");
863 fun = sy->out[fid].out;
865 call = ast_call_new(sy->ops[sy->ops_count].ctx, fun);
867 parseerror(parser, "out of memory");
871 if (fid+1 == sy->out_count) {
874 } else if (fid+2 == sy->out_count) {
877 params = sy->out[sy->out_count].block;
881 if (!ast_call_params_add(call, sy->out[sy->out_count].out)) {
882 ast_delete(sy->out[sy->out_count].out);
883 parseerror(parser, "out of memory");
887 paramcount = params->exprs_count;
888 MEM_VECTOR_MOVE(params, exprs, call, params);
891 if (!ast_call_check_types(call))
894 parseerror(parser, "invalid function call");
898 /* overwrite fid, the function, with a call */
899 sy->out[fid] = syexp(call->expression.node.context, (ast_expression*)call);
901 if (fun->expression.vtype != TYPE_FUNCTION) {
902 parseerror(parser, "not a function (%s)", type_name[fun->expression.vtype]);
906 if (!fun->expression.next) {
907 parseerror(parser, "could not determine function return type");
910 if (fun->expression.params_count != paramcount &&
911 !(fun->expression.variadic &&
912 fun->expression.params_count < paramcount))
915 const char *fewmany = (fun->expression.params_count > paramcount) ? "few" : "many";
917 fval = (ast_istype(fun, ast_value) ? ((ast_value*)fun) : NULL);
918 if (opts_standard == COMPILER_GMQCC)
921 parseerror(parser, "too %s parameters for call to %s: expected %i, got %i\n"
922 " -> `%s` has been declared here: %s:%i",
923 fewmany, fval->name, (int)fun->expression.params_count, (int)paramcount,
924 fval->name, ast_ctx(fun).file, (int)ast_ctx(fun).line);
926 parseerror(parser, "too %s parameters for function call: expected %i, got %i\n"
927 " -> `%s` has been declared here: %s:%i",
928 fewmany, fval->name, (int)fun->expression.params_count, (int)paramcount,
929 fval->name, ast_ctx(fun).file, (int)ast_ctx(fun).line);
935 return !parsewarning(parser, WARN_TOO_FEW_PARAMETERS,
936 "too %s parameters for call to %s: expected %i, got %i\n"
937 " -> `%s` has been declared here: %s:%i",
938 fewmany, fval->name, (int)fun->expression.params_count, (int)paramcount,
939 fval->name, ast_ctx(fun).file, (int)ast_ctx(fun).line);
941 return !parsewarning(parser, WARN_TOO_FEW_PARAMETERS,
942 "too %s parameters for function call: expected %i, got %i\n"
943 " -> `%s` has been declared here: %s:%i",
944 fewmany, fval->name, (int)fun->expression.params_count, (int)paramcount,
945 fval->name, ast_ctx(fun).file, (int)ast_ctx(fun).line);
953 static bool parser_close_paren(parser_t *parser, shunt *sy, bool functions_only)
955 if (!sy->ops_count) {
956 parseerror(parser, "unmatched closing paren");
959 /* this would for bit a + (x) because there are no operators inside (x)
960 if (sy->ops[sy->ops_count-1].paren == 1) {
961 parseerror(parser, "empty parenthesis expression");
965 while (sy->ops_count) {
966 if (sy->ops[sy->ops_count-1].paren == 'f') {
967 if (!parser_close_call(parser, sy))
971 if (sy->ops[sy->ops_count-1].paren == 1) {
973 return !functions_only;
975 if (!parser_sy_pop(parser, sy))
981 static void parser_reclassify_token(parser_t *parser)
984 for (i = 0; i < operator_count; ++i) {
985 if (!strcmp(parser_tokval(parser), operators[i].op)) {
986 parser->tok = TOKEN_OPERATOR;
992 static ast_expression* parse_expression_leave(parser_t *parser, bool stopatcomma)
994 ast_expression *expr = NULL;
997 bool gotmemberof = false;
999 /* count the parens because an if starts with one, so the
1000 * end of a condition is an unmatched closing paren
1004 MEM_VECTOR_INIT(&sy, out);
1005 MEM_VECTOR_INIT(&sy, ops);
1007 parser->lex->flags.noops = false;
1009 parser_reclassify_token(parser);
1014 gotmemberof = false;
1016 parser->memberof = 0;
1018 if (parser->tok == TOKEN_IDENT)
1020 ast_expression *var;
1022 parseerror(parser, "expected operator or end of statement");
1027 if (opts_standard == COMPILER_GMQCC)
1029 if (parser->memberof == TYPE_ENTITY) {
1030 /* still get vars first since there could be a fieldpointer */
1031 var = parser_find_var(parser, parser_tokval(parser));
1033 var = parser_find_field(parser, parser_tokval(parser));
1035 else if (parser->memberof == TYPE_VECTOR)
1037 parseerror(parser, "TODO: implement effective vector member access");
1040 else if (parser->memberof) {
1041 parseerror(parser, "namespace for member not found");
1045 var = parser_find_var(parser, parser_tokval(parser));
1047 var = parser_find_var(parser, parser_tokval(parser));
1049 var = parser_find_field(parser, parser_tokval(parser));
1052 parseerror(parser, "unexpected ident: %s", parser_tokval(parser));
1055 if (ast_istype(var, ast_value))
1056 ((ast_value*)var)->uses++;
1057 if (!shunt_out_add(&sy, syexp(parser_ctx(parser), var))) {
1058 parseerror(parser, "out of memory");
1061 DEBUGSHUNTDO(printf("push %s\n", parser_tokval(parser)));
1063 else if (parser->tok == TOKEN_FLOATCONST) {
1066 parseerror(parser, "expected operator or end of statement, got constant");
1070 val = parser_const_float(parser, (parser_token(parser)->constval.f));
1073 if (!shunt_out_add(&sy, syexp(parser_ctx(parser), (ast_expression*)val))) {
1074 parseerror(parser, "out of memory");
1077 DEBUGSHUNTDO(printf("push %g\n", parser_token(parser)->constval.f));
1079 else if (parser->tok == TOKEN_INTCONST) {
1082 parseerror(parser, "expected operator or end of statement, got constant");
1086 val = parser_const_float(parser, (double)(parser_token(parser)->constval.i));
1089 if (!shunt_out_add(&sy, syexp(parser_ctx(parser), (ast_expression*)val))) {
1090 parseerror(parser, "out of memory");
1093 DEBUGSHUNTDO(printf("push %i\n", parser_token(parser)->constval.i));
1095 else if (parser->tok == TOKEN_STRINGCONST) {
1098 parseerror(parser, "expected operator or end of statement, got constant");
1102 val = parser_const_string(parser, parser_tokval(parser));
1105 if (!shunt_out_add(&sy, syexp(parser_ctx(parser), (ast_expression*)val))) {
1106 parseerror(parser, "out of memory");
1109 DEBUGSHUNTDO(printf("push string\n"));
1111 else if (parser->tok == TOKEN_VECTORCONST) {
1114 parseerror(parser, "expected operator or end of statement, got constant");
1118 val = parser_const_vector(parser, parser_token(parser)->constval.v);
1121 if (!shunt_out_add(&sy, syexp(parser_ctx(parser), (ast_expression*)val))) {
1122 parseerror(parser, "out of memory");
1125 DEBUGSHUNTDO(printf("push '%g %g %g'\n",
1126 parser_token(parser)->constval.v.x,
1127 parser_token(parser)->constval.v.y,
1128 parser_token(parser)->constval.v.z));
1130 else if (parser->tok == '(') {
1131 parseerror(parser, "internal error: '(' should be classified as operator");
1134 else if (parser->tok == ')') {
1136 DEBUGSHUNTDO(printf("do[op] )\n"));
1140 /* we do expect an operator next */
1141 /* closing an opening paren */
1142 if (!parser_close_paren(parser, &sy, false))
1145 DEBUGSHUNTDO(printf("do[nop] )\n"));
1149 /* allowed for function calls */
1150 if (!parser_close_paren(parser, &sy, true))
1155 else if (parser->tok != TOKEN_OPERATOR) {
1157 parseerror(parser, "expected operator or end of statement");
1164 /* classify the operator */
1165 /* TODO: suffix operators */
1166 const oper_info *op;
1167 const oper_info *olast = NULL;
1169 for (o = 0; o < operator_count; ++o) {
1170 if ((!(operators[o].flags & OP_PREFIX) == wantop) &&
1171 !(operators[o].flags & OP_SUFFIX) && /* remove this */
1172 !strcmp(parser_tokval(parser), operators[o].op))
1177 if (o == operator_count) {
1178 /* no operator found... must be the end of the statement */
1181 /* found an operator */
1184 /* when declaring variables, a comma starts a new variable */
1185 if (op->id == opid1(',') && !parens && stopatcomma) {
1186 /* fixup the token */
1191 if (sy.ops_count && !sy.ops[sy.ops_count-1].paren)
1192 olast = &operators[sy.ops[sy.ops_count-1].etype-1];
1195 (op->prec < olast->prec) ||
1196 (op->assoc == ASSOC_LEFT && op->prec <= olast->prec) ) )
1198 if (!parser_sy_pop(parser, &sy))
1200 if (sy.ops_count && !sy.ops[sy.ops_count-1].paren)
1201 olast = &operators[sy.ops[sy.ops_count-1].etype-1];
1206 if (op->id == opid1('.') && opts_standard == COMPILER_GMQCC) {
1207 /* for gmqcc standard: open up the namespace of the previous type */
1208 ast_expression *prevex = sy.out[sy.out_count-1].out;
1210 parseerror(parser, "unexpected member operator");
1213 if (prevex->expression.vtype == TYPE_ENTITY)
1214 parser->memberof = TYPE_ENTITY;
1215 else if (prevex->expression.vtype == TYPE_VECTOR)
1216 parser->memberof = TYPE_VECTOR;
1218 parseerror(parser, "type error: type has no members");
1224 if (op->id == opid1('(')) {
1226 DEBUGSHUNTDO(printf("push [op] (\n"));
1228 /* we expected an operator, this is the function-call operator */
1229 if (!shunt_ops_add(&sy, syparen(parser_ctx(parser), 'f', sy.out_count-1))) {
1230 parseerror(parser, "out of memory");
1235 if (!shunt_ops_add(&sy, syparen(parser_ctx(parser), 1, 0))) {
1236 parseerror(parser, "out of memory");
1239 DEBUGSHUNTDO(printf("push [nop] (\n"));
1243 DEBUGSHUNTDO(printf("push operator %s\n", op->op));
1244 if (!shunt_ops_add(&sy, syop(parser_ctx(parser), op)))
1249 if (!parser_next(parser)) {
1252 if (parser->tok == ';' || parser->tok == ']') {
1257 while (sy.ops_count) {
1258 if (!parser_sy_pop(parser, &sy))
1262 parser->lex->flags.noops = true;
1263 if (!sy.out_count) {
1264 parseerror(parser, "empty expression");
1267 expr = sy.out[0].out;
1268 MEM_VECTOR_CLEAR(&sy, out);
1269 MEM_VECTOR_CLEAR(&sy, ops);
1270 DEBUGSHUNTDO(printf("shunt done\n"));
1274 parser->lex->flags.noops = true;
1275 MEM_VECTOR_CLEAR(&sy, out);
1276 MEM_VECTOR_CLEAR(&sy, ops);
1280 static ast_expression* parse_expression(parser_t *parser, bool stopatcomma)
1282 ast_expression *e = parse_expression_leave(parser, stopatcomma);
1285 if (!parser_next(parser)) {
1292 static bool parse_if(parser_t *parser, ast_block *block, ast_expression **out)
1295 ast_expression *cond, *ontrue, *onfalse = NULL;
1297 lex_ctx ctx = parser_ctx(parser);
1299 /* skip the 'if' and check for opening paren */
1300 if (!parser_next(parser) || parser->tok != '(') {
1301 parseerror(parser, "expected 'if' condition in parenthesis");
1304 /* parse into the expression */
1305 if (!parser_next(parser)) {
1306 parseerror(parser, "expected 'if' condition after opening paren");
1309 /* parse the condition */
1310 cond = parse_expression_leave(parser, false);
1314 if (parser->tok != ')') {
1315 parseerror(parser, "expected closing paren after 'if' condition");
1319 /* parse into the 'then' branch */
1320 if (!parser_next(parser)) {
1321 parseerror(parser, "expected statement for on-true branch of 'if'");
1325 ontrue = parse_statement_or_block(parser);
1330 /* check for an else */
1331 if (!strcmp(parser_tokval(parser), "else")) {
1332 /* parse into the 'else' branch */
1333 if (!parser_next(parser)) {
1334 parseerror(parser, "expected on-false branch after 'else'");
1339 onfalse = parse_statement_or_block(parser);
1347 ifthen = ast_ifthen_new(ctx, cond, ontrue, onfalse);
1348 *out = (ast_expression*)ifthen;
1352 static bool parse_while(parser_t *parser, ast_block *block, ast_expression **out)
1355 ast_expression *cond, *ontrue;
1357 lex_ctx ctx = parser_ctx(parser);
1359 /* skip the 'while' and check for opening paren */
1360 if (!parser_next(parser) || parser->tok != '(') {
1361 parseerror(parser, "expected 'while' condition in parenthesis");
1364 /* parse into the expression */
1365 if (!parser_next(parser)) {
1366 parseerror(parser, "expected 'while' condition after opening paren");
1369 /* parse the condition */
1370 cond = parse_expression_leave(parser, false);
1374 if (parser->tok != ')') {
1375 parseerror(parser, "expected closing paren after 'while' condition");
1379 /* parse into the 'then' branch */
1380 if (!parser_next(parser)) {
1381 parseerror(parser, "expected while-loop body");
1385 ontrue = parse_statement_or_block(parser);
1391 aloop = ast_loop_new(ctx, NULL, cond, NULL, NULL, ontrue);
1392 *out = (ast_expression*)aloop;
1396 static bool parse_dowhile(parser_t *parser, ast_block *block, ast_expression **out)
1399 ast_expression *cond, *ontrue;
1401 lex_ctx ctx = parser_ctx(parser);
1403 /* skip the 'do' and get the body */
1404 if (!parser_next(parser)) {
1405 parseerror(parser, "expected loop body");
1408 ontrue = parse_statement_or_block(parser);
1412 /* expect the "while" */
1413 if (parser->tok != TOKEN_KEYWORD ||
1414 strcmp(parser_tokval(parser), "while"))
1416 parseerror(parser, "expected 'while' and condition");
1421 /* skip the 'while' and check for opening paren */
1422 if (!parser_next(parser) || parser->tok != '(') {
1423 parseerror(parser, "expected 'while' condition in parenthesis");
1427 /* parse into the expression */
1428 if (!parser_next(parser)) {
1429 parseerror(parser, "expected 'while' condition after opening paren");
1433 /* parse the condition */
1434 cond = parse_expression_leave(parser, false);
1438 if (parser->tok != ')') {
1439 parseerror(parser, "expected closing paren after 'while' condition");
1445 if (!parser_next(parser) || parser->tok != ';') {
1446 parseerror(parser, "expected semicolon after condition");
1452 if (!parser_next(parser)) {
1453 parseerror(parser, "parse error");
1459 aloop = ast_loop_new(ctx, NULL, NULL, cond, NULL, ontrue);
1460 *out = (ast_expression*)aloop;
1464 static bool parse_for(parser_t *parser, ast_block *block, ast_expression **out)
1467 ast_expression *initexpr, *cond, *increment, *ontrue;
1468 size_t oldblocklocal;
1471 lex_ctx ctx = parser_ctx(parser);
1473 oldblocklocal = parser->blocklocal;
1474 parser->blocklocal = parser->locals_count;
1481 /* skip the 'while' and check for opening paren */
1482 if (!parser_next(parser) || parser->tok != '(') {
1483 parseerror(parser, "expected 'for' expressions in parenthesis");
1486 /* parse into the expression */
1487 if (!parser_next(parser)) {
1488 parseerror(parser, "expected 'for' initializer after opening paren");
1492 if (parser->tok == TOKEN_TYPENAME) {
1493 if (opts_standard != COMPILER_GMQCC) {
1494 if (parsewarning(parser, WARN_EXTENSIONS,
1495 "current standard does not allow variable declarations in for-loop initializers"))
1499 parseerror(parser, "TODO: assignment of new variables to be non-const");
1501 if (!parse_variable(parser, block))
1504 else if (parser->tok != ';')
1506 initexpr = parse_expression_leave(parser, false);
1511 /* move on to condition */
1512 if (parser->tok != ';') {
1513 parseerror(parser, "expected semicolon after for-loop initializer");
1516 if (!parser_next(parser)) {
1517 parseerror(parser, "expected for-loop condition");
1521 /* parse the condition */
1522 if (parser->tok != ';') {
1523 cond = parse_expression_leave(parser, false);
1528 /* move on to incrementor */
1529 if (parser->tok != ';') {
1530 parseerror(parser, "expected semicolon after for-loop initializer");
1533 if (!parser_next(parser)) {
1534 parseerror(parser, "expected for-loop condition");
1538 /* parse the incrementor */
1539 if (parser->tok != ')') {
1540 increment = parse_expression_leave(parser, false);
1543 if (!ast_istype(increment, ast_store) &&
1544 !ast_istype(increment, ast_call) &&
1545 !ast_istype(increment, ast_binstore))
1547 if (genwarning(ast_ctx(increment), WARN_EFFECTLESS_STATEMENT, "statement has no effect"))
1553 if (parser->tok != ')') {
1554 parseerror(parser, "expected closing paren after 'for-loop' incrementor");
1557 /* parse into the 'then' branch */
1558 if (!parser_next(parser)) {
1559 parseerror(parser, "expected for-loop body");
1562 ontrue = parse_statement_or_block(parser);
1567 aloop = ast_loop_new(ctx, initexpr, cond, NULL, increment, ontrue);
1568 *out = (ast_expression*)aloop;
1570 while (parser->locals_count > parser->blocklocal)
1571 retval = retval && parser_pop_local(parser);
1572 parser->blocklocal = oldblocklocal;
1575 if (initexpr) ast_delete(initexpr);
1576 if (cond) ast_delete(cond);
1577 if (increment) ast_delete(increment);
1578 while (parser->locals_count > parser->blocklocal)
1579 (void)!parser_pop_local(parser);
1580 parser->blocklocal = oldblocklocal;
1584 static bool parse_statement(parser_t *parser, ast_block *block, ast_expression **out)
1586 if (parser->tok == TOKEN_TYPENAME)
1588 /* local variable */
1590 parseerror(parser, "cannot declare a variable from here");
1593 if (opts_standard == COMPILER_QCC) {
1594 if (parsewarning(parser, WARN_EXTENSIONS, "missing 'local' keyword when declaring a local variable"))
1597 if (!parse_variable(parser, block))
1602 else if (parser->tok == TOKEN_KEYWORD)
1604 if (!strcmp(parser_tokval(parser), "local"))
1607 parseerror(parser, "cannot declare a local variable here");
1610 if (!parser_next(parser)) {
1611 parseerror(parser, "expected variable declaration");
1614 if (!parse_variable(parser, block))
1619 else if (!strcmp(parser_tokval(parser), "return"))
1621 ast_expression *exp = NULL;
1622 ast_return *ret = NULL;
1623 ast_value *expected = parser->function->vtype;
1625 if (!parser_next(parser)) {
1626 parseerror(parser, "expected return expression");
1630 if (parser->tok != ';') {
1631 exp = parse_expression(parser, false);
1635 if (exp->expression.vtype != expected->expression.next->expression.vtype) {
1636 parseerror(parser, "return with invalid expression");
1639 ret = ast_return_new(exp->expression.node.context, exp);
1645 if (!parser_next(parser))
1646 parseerror(parser, "parse error");
1647 if (expected->expression.next->expression.vtype != TYPE_VOID) {
1648 if (opts_standard != COMPILER_GMQCC)
1649 (void)!parsewarning(parser, WARN_MISSING_RETURN_VALUES, "return without value");
1651 parseerror(parser, "return without value");
1653 ret = ast_return_new(parser_ctx(parser), NULL);
1655 *out = (ast_expression*)ret;
1658 else if (!strcmp(parser_tokval(parser), "if"))
1660 return parse_if(parser, block, out);
1662 else if (!strcmp(parser_tokval(parser), "while"))
1664 return parse_while(parser, block, out);
1666 else if (!strcmp(parser_tokval(parser), "do"))
1668 return parse_dowhile(parser, block, out);
1670 else if (!strcmp(parser_tokval(parser), "for"))
1672 if (opts_standard == COMPILER_QCC) {
1673 if (parsewarning(parser, WARN_EXTENSIONS, "for loops are not recognized in the original Quake C standard, to enable try an alternate standard --std=?"))
1676 return parse_for(parser, block, out);
1678 parseerror(parser, "Unexpected keyword");
1681 else if (parser->tok == '{')
1684 inner = parse_block(parser, false);
1687 *out = (ast_expression*)inner;
1692 ast_expression *exp = parse_expression(parser, false);
1696 if (!ast_istype(exp, ast_store) &&
1697 !ast_istype(exp, ast_call) &&
1698 !ast_istype(exp, ast_binstore))
1700 if (genwarning(ast_ctx(exp), WARN_EFFECTLESS_STATEMENT, "statement has no effect"))
1707 static bool GMQCC_WARN parser_pop_local(parser_t *parser)
1710 parser->locals_count--;
1712 ve = &parser->locals[parser->locals_count];
1713 if (ast_istype(ve->var, ast_value) && !(((ast_value*)(ve->var))->uses)) {
1714 if (parsewarning(parser, WARN_UNUSED_VARIABLE, "unused variable: `%s`", ve->name))
1717 mem_d(parser->locals[parser->locals_count].name);
1721 static bool parse_block_into(parser_t *parser, ast_block *block, bool warnreturn)
1723 size_t oldblocklocal;
1726 oldblocklocal = parser->blocklocal;
1727 parser->blocklocal = parser->locals_count;
1729 if (!parser_next(parser)) { /* skip the '{' */
1730 parseerror(parser, "expected function body");
1734 while (parser->tok != TOKEN_EOF && parser->tok < TOKEN_ERROR)
1736 ast_expression *expr;
1737 if (parser->tok == '}')
1740 if (!parse_statement(parser, block, &expr)) {
1741 /* parseerror(parser, "parse error"); */
1747 if (!ast_block_exprs_add(block, expr)) {
1754 if (parser->tok != '}') {
1757 if (warnreturn && parser->function->vtype->expression.next->expression.vtype != TYPE_VOID)
1759 if (!block->exprs_count ||
1760 !ast_istype(block->exprs[block->exprs_count-1], ast_return))
1762 if (parsewarning(parser, WARN_MISSING_RETURN_VALUES, "control reaches end of non-void function")) {
1768 (void)parser_next(parser);
1772 while (parser->locals_count > parser->blocklocal)
1773 retval = retval && parser_pop_local(parser);
1774 parser->blocklocal = oldblocklocal;
1778 static ast_block* parse_block(parser_t *parser, bool warnreturn)
1781 block = ast_block_new(parser_ctx(parser));
1784 if (!parse_block_into(parser, block, warnreturn)) {
1785 ast_block_delete(block);
1791 static ast_expression* parse_statement_or_block(parser_t *parser)
1793 ast_expression *expr = NULL;
1794 if (parser->tok == '{')
1795 return (ast_expression*)parse_block(parser, false);
1796 if (!parse_statement(parser, NULL, &expr))
1802 static bool create_vector_members(parser_t *parser, ast_value *var, varentry_t *ve)
1805 size_t len = strlen(var->name);
1807 for (i = 0; i < 3; ++i) {
1808 ve[i].var = (ast_expression*)ast_member_new(ast_ctx(var), (ast_expression*)var, i);
1812 ve[i].name = (char*)mem_a(len+3);
1814 ast_delete(ve[i].var);
1818 memcpy(ve[i].name, var->name, len);
1819 ve[i].name[len] = '_';
1820 ve[i].name[len+1] = 'x'+i;
1821 ve[i].name[len+2] = 0;
1830 ast_delete(ve[i].var);
1837 static bool parse_function_body(parser_t *parser, ast_value *var)
1839 ast_block *block = NULL;
1844 ast_expression *framenum = NULL;
1845 ast_expression *nextthink = NULL;
1846 /* None of the following have to be deleted */
1847 ast_expression *fld_think = NULL, *fld_nextthink = NULL, *fld_frame = NULL;
1848 ast_expression *gbl_time = NULL, *gbl_self = NULL;
1849 bool has_frame_think;
1853 has_frame_think = false;
1854 old = parser->function;
1856 if (var->expression.variadic) {
1857 if (parsewarning(parser, WARN_VARIADIC_FUNCTION,
1858 "variadic function with implementation will not be able to access additional parameters"))
1864 if (parser->tok == '[') {
1865 /* got a frame definition: [ framenum, nextthink ]
1866 * this translates to:
1867 * self.frame = framenum;
1868 * self.nextthink = time + 0.1;
1869 * self.think = nextthink;
1873 fld_think = parser_find_field(parser, "think");
1874 fld_nextthink = parser_find_field(parser, "nextthink");
1875 fld_frame = parser_find_field(parser, "frame");
1876 if (!fld_think || !fld_nextthink || !fld_frame) {
1877 parseerror(parser, "cannot use [frame,think] notation without the required fields");
1878 parseerror(parser, "please declare the following entityfields: `frame`, `think`, `nextthink`");
1881 gbl_time = parser_find_global(parser, "time");
1882 gbl_self = parser_find_global(parser, "self");
1883 if (!gbl_time || !gbl_self) {
1884 parseerror(parser, "cannot use [frame,think] notation without the required globals");
1885 parseerror(parser, "please declare the following globals: `time`, `self`");
1889 if (!parser_next(parser))
1892 framenum = parse_expression_leave(parser, true);
1894 parseerror(parser, "expected a framenumber constant in[frame,think] notation");
1897 if (!ast_istype(framenum, ast_value) || !( (ast_value*)framenum )->isconst) {
1898 ast_unref(framenum);
1899 parseerror(parser, "framenumber in [frame,think] notation must be a constant");
1903 if (parser->tok != ',') {
1904 ast_unref(framenum);
1905 parseerror(parser, "expected comma after frame number in [frame,think] notation");
1906 parseerror(parser, "Got a %i\n", parser->tok);
1910 if (!parser_next(parser)) {
1911 ast_unref(framenum);
1915 if (parser->tok == TOKEN_IDENT && !parser_find_var(parser, parser_tokval(parser)))
1917 /* qc allows the use of not-yet-declared functions here
1918 * - this automatically creates a prototype */
1920 ast_value *thinkfunc;
1921 ast_expression *functype = fld_think->expression.next;
1923 thinkfunc = ast_value_new(parser_ctx(parser), parser_tokval(parser), functype->expression.vtype);
1924 if (!thinkfunc || !ast_type_adopt(thinkfunc, functype)) {
1925 ast_unref(framenum);
1926 parseerror(parser, "failed to create implicit prototype for `%s`", parser_tokval(parser));
1930 if (!parser_next(parser)) {
1931 ast_unref(framenum);
1932 ast_delete(thinkfunc);
1936 varent.var = (ast_expression*)thinkfunc;
1937 varent.name = util_strdup(thinkfunc->name);
1938 if (!parser_t_globals_add(parser, varent)) {
1939 ast_unref(framenum);
1940 ast_delete(thinkfunc);
1943 nextthink = (ast_expression*)thinkfunc;
1946 nextthink = parse_expression_leave(parser, true);
1948 ast_unref(framenum);
1949 parseerror(parser, "expected a think-function in [frame,think] notation");
1954 if (!ast_istype(nextthink, ast_value)) {
1955 parseerror(parser, "think-function in [frame,think] notation must be a constant");
1959 if (retval && parser->tok != ']') {
1960 parseerror(parser, "expected closing `]` for [frame,think] notation");
1964 if (retval && !parser_next(parser)) {
1968 if (retval && parser->tok != '{') {
1969 parseerror(parser, "a function body has to be declared after a [frame,think] declaration");
1974 ast_unref(nextthink);
1975 ast_unref(framenum);
1979 has_frame_think = true;
1982 block = ast_block_new(parser_ctx(parser));
1984 parseerror(parser, "failed to allocate block");
1985 if (has_frame_think) {
1986 ast_unref(nextthink);
1987 ast_unref(framenum);
1992 if (has_frame_think) {
1994 ast_expression *self_frame;
1995 ast_expression *self_nextthink;
1996 ast_expression *self_think;
1997 ast_expression *time_plus_1;
1998 ast_store *store_frame;
1999 ast_store *store_nextthink;
2000 ast_store *store_think;
2002 ctx = parser_ctx(parser);
2003 self_frame = (ast_expression*)ast_entfield_new(ctx, gbl_self, fld_frame);
2004 self_nextthink = (ast_expression*)ast_entfield_new(ctx, gbl_self, fld_nextthink);
2005 self_think = (ast_expression*)ast_entfield_new(ctx, gbl_self, fld_think);
2007 time_plus_1 = (ast_expression*)ast_binary_new(ctx, INSTR_ADD_F,
2008 gbl_time, (ast_expression*)parser_const_float(parser, 0.1));
2010 if (!self_frame || !self_nextthink || !self_think || !time_plus_1) {
2011 if (self_frame) ast_delete(self_frame);
2012 if (self_nextthink) ast_delete(self_nextthink);
2013 if (self_think) ast_delete(self_think);
2014 if (time_plus_1) ast_delete(time_plus_1);
2020 store_frame = ast_store_new(ctx, INSTR_STOREP_F, self_frame, framenum);
2021 store_nextthink = ast_store_new(ctx, INSTR_STOREP_F, self_nextthink, time_plus_1);
2022 store_think = ast_store_new(ctx, INSTR_STOREP_FNC, self_think, nextthink);
2025 ast_delete(self_frame);
2028 if (!store_nextthink) {
2029 ast_delete(self_nextthink);
2033 ast_delete(self_think);
2037 if (store_frame) ast_delete(store_frame);
2038 if (store_nextthink) ast_delete(store_nextthink);
2039 if (store_think) ast_delete(store_think);
2042 if (retval && !ast_block_exprs_add(block, (ast_expression*)store_frame)) {
2043 ast_delete(store_frame);
2044 ast_delete(store_nextthink);
2045 ast_delete(store_think);
2049 if (retval && !ast_block_exprs_add(block, (ast_expression*)store_nextthink)) {
2050 ast_delete(store_nextthink);
2051 ast_delete(store_think);
2055 if (retval && !ast_block_exprs_add(block, (ast_expression*)store_think) )
2057 ast_delete(store_think);
2063 parseerror(parser, "failed to generate code for [frame,think]");
2064 ast_unref(nextthink);
2065 ast_unref(framenum);
2071 for (parami = 0; parami < var->expression.params_count; ++parami) {
2074 ast_value *param = var->expression.params[parami];
2076 if (param->expression.vtype != TYPE_VECTOR &&
2077 (param->expression.vtype != TYPE_FIELD ||
2078 param->expression.next->expression.vtype != TYPE_VECTOR))
2083 if (!create_vector_members(parser, param, ve)) {
2084 ast_block_delete(block);
2088 for (e = 0; e < 3; ++e) {
2089 if (!parser_t_locals_add(parser, ve[e]))
2091 if (!ast_block_collect(block, ve[e].var)) {
2092 parser->locals_count--;
2095 ve[e].var = NULL; /* collected */
2098 parser->locals -= e;
2103 ast_block_delete(block);
2108 func = ast_function_new(ast_ctx(var), var->name, var);
2110 parseerror(parser, "failed to allocate function for `%s`", var->name);
2111 ast_block_delete(block);
2114 if (!parser_t_functions_add(parser, func)) {
2115 parseerror(parser, "failed to allocate slot for function `%s`", var->name);
2116 ast_block_delete(block);
2120 parser->function = func;
2121 if (!parse_block_into(parser, block, true)) {
2122 ast_block_delete(block);
2126 if (!ast_function_blocks_add(func, block)) {
2127 ast_block_delete(block);
2131 parser->function = old;
2132 while (parser->locals_count)
2133 retval = retval && parser_pop_local(parser);
2135 if (parser->tok == ';')
2136 return parser_next(parser);
2137 else if (opts_standard == COMPILER_QCC)
2138 parseerror(parser, "missing semicolon after function body (mandatory with -std=qcc)");
2142 parser->functions_count--;
2144 ast_function_delete(func);
2145 var->constval.vfunc = NULL;
2148 while (parser->locals_count) {
2149 parser->locals_count--;
2150 mem_d(parser->locals[parser->locals_count].name);
2152 parser->function = old;
2157 MEM_VECTOR_MAKE(ast_value*, p);
2159 MEM_VEC_FUNCTIONS(paramlist_t, ast_value*, p)
2161 static ast_value *parse_typename(parser_t *parser, ast_value **storebase);
2162 static ast_value *parse_parameter_list(parser_t *parser, ast_value *var)
2170 bool variadic = false;
2172 ctx = parser_ctx(parser);
2174 /* for the sake of less code we parse-in in this function */
2175 if (!parser_next(parser)) {
2176 parseerror(parser, "expected parameter list");
2180 MEM_VECTOR_INIT(¶ms, p);
2182 /* parse variables until we hit a closing paren */
2183 while (parser->tok != ')') {
2185 /* there must be commas between them */
2186 if (parser->tok != ',') {
2187 parseerror(parser, "expected comma or end of parameter list");
2190 if (!parser_next(parser)) {
2191 parseerror(parser, "expected parameter");
2197 if (parser->tok == TOKEN_DOTS) {
2198 /* '...' indicates a varargs function */
2200 if (!parser_next(parser)) {
2201 parseerror(parser, "expected parameter");
2204 if (parser->tok != ')') {
2205 parseerror(parser, "`...` must be the last parameter of a variadic function declaration");
2211 /* for anything else just parse a typename */
2212 param = parse_typename(parser, NULL);
2215 if (!paramlist_t_p_add(¶ms, param))
2221 if (params.p_count > 8)
2222 parseerror(parser, "more than 8 parameters are currently not supported");
2225 if (!parser_next(parser)) {
2226 parseerror(parser, "parse error after typename");
2230 /* now turn 'var' into a function type */
2231 fval = ast_value_new(ctx, "<type()>", TYPE_FUNCTION);
2232 fval->expression.next = (ast_expression*)var;
2233 fval->expression.variadic = variadic;
2236 MEM_VECTOR_MOVE(¶ms, p, &var->expression, params);
2242 for (i = 0; i < params.p_count; ++i)
2243 ast_delete(params.p[i]);
2244 MEM_VECTOR_CLEAR(¶ms, p);
2248 /* Parse a complete typename.
2249 * for single-variables (ie. function parameters or typedefs) storebase should be NULL
2250 * but when parsing variables separated by comma
2251 * 'storebase' should point to where the base-type should be kept.
2252 * The base type makes up every bit of type information which comes *before* the
2255 * The following will be parsed in its entirety:
2257 * The 'basetype' in this case is 'void()'
2258 * and if there's a comma after it, say:
2260 * then the type-information 'void()' can be stored in 'storebase'
2262 static ast_value *parse_typename(parser_t *parser, ast_value **storebase)
2264 ast_value *var, *tmp;
2267 const char *name = NULL;
2268 bool isfield = false;
2270 ctx = parser_ctx(parser);
2272 /* types may start with a dot */
2273 if (parser->tok == '.') {
2275 /* if we parsed a dot we need a typename now */
2276 if (!parser_next(parser)) {
2277 parseerror(parser, "expected typename for field definition");
2280 if (parser->tok != TOKEN_TYPENAME) {
2281 parseerror(parser, "expected typename");
2286 /* generate the basic type value */
2287 var = ast_value_new(ctx, "<type>", parser_token(parser)->constval.t);
2288 /* do not yet turn into a field - remember:
2289 * .void() foo; is a field too
2290 * .void()() foo; is a function
2294 if (!parser_next(parser)) {
2296 parseerror(parser, "parse error after typename");
2300 /* an opening paren now starts the parameter-list of a function */
2301 if (parser->tok == '(') {
2302 var = parse_parameter_list(parser, var);
2306 /* This is the point where we can turn it into a field */
2308 /* turn it into a field if desired */
2309 tmp = ast_value_new(ctx, "<type:f>", TYPE_FIELD);
2310 tmp->expression.next = (ast_expression*)var;
2314 while (parser->tok == '(') {
2315 var = parse_parameter_list(parser, var);
2320 /* store the base if requested */
2322 *storebase = ast_value_copy(var);
2325 /* there may be a name now */
2326 if (parser->tok == TOKEN_IDENT) {
2327 name = util_strdup(parser_tokval(parser));
2329 if (!parser_next(parser)) {
2330 parseerror(parser, "error after variable or field declaration");
2335 /* now there may be function parens again */
2336 while (parser->tok == '(') {
2337 var = parse_parameter_list(parser, var);
2345 /* finally name it */
2347 if (!ast_value_set_name(var, name)) {
2349 parseerror(parser, "internal error: failed to set name");
2352 /* free the name, ast_value_set_name duplicates */
2359 static bool parse_variable(parser_t *parser, ast_block *localblock)
2363 ast_expression *old;
2367 ast_value *basetype = NULL;
2369 bool isparam = false;
2370 bool isvector = false;
2371 bool cleanvar = true;
2373 varentry_t varent, ve[3];
2375 /* get the first complete variable */
2376 var = parse_typename(parser, &basetype);
2379 ast_delete(basetype);
2383 memset(&varent, 0, sizeof(varent));
2384 memset(&ve, 0, sizeof(ve));
2389 /* Part 0: finish the type */
2390 while (parser->tok == '(') {
2391 var = parse_parameter_list(parser, var);
2399 * check for validity: (end_sys_..., multiple-definitions, prototypes, ...)
2400 * Also: if there was a prototype, `var` will be deleted and set to `proto` which
2401 * is then filled with the previous definition and the parameter-names replaced.
2404 /* Deal with end_sys_ vars */
2406 if (!strcmp(var->name, "end_sys_globals")) {
2407 parser->crc_globals = parser->globals_count;
2410 else if (!strcmp(var->name, "end_sys_fields")) {
2411 parser->crc_fields = parser->fields_count;
2414 if (was_end && var->expression.vtype == TYPE_FIELD) {
2415 if (parsewarning(parser, WARN_END_SYS_FIELDS,
2416 "global '%s' hint should not be a field",
2417 parser_tokval(parser)))
2424 if (var->expression.vtype == TYPE_FIELD)
2426 /* deal with field declarations */
2427 old = parser_find_field(parser, var->name);
2429 if (parsewarning(parser, WARN_FIELD_REDECLARED, "field `%s` already declared here: %s:%i",
2430 var->name, ast_ctx(old).file, (int)ast_ctx(old).line))
2439 parseerror(parser, "field `%s` already declared here: %s:%i",
2440 var->name, ast_ctx(old).file, ast_ctx(old).line);
2445 if (opts_standard == COMPILER_QCC &&
2446 (old = parser_find_global(parser, var->name)))
2448 parseerror(parser, "cannot declare a field and a global of the same name with -std=qcc");
2449 parseerror(parser, "field `%s` already declared here: %s:%i",
2450 var->name, ast_ctx(old).file, ast_ctx(old).line);
2457 /* deal with other globals */
2458 old = parser_find_global(parser, var->name);
2459 if (old && var->expression.vtype == TYPE_FUNCTION && old->expression.vtype == TYPE_FUNCTION)
2461 /* This is a function which had a prototype */
2462 if (!ast_istype(old, ast_value)) {
2463 parseerror(parser, "internal error: prototype is not an ast_value");
2467 proto = (ast_value*)old;
2468 if (!ast_compare_type((ast_expression*)proto, (ast_expression*)var)) {
2469 parseerror(parser, "conflicting types for `%s`, previous declaration was here: %s:%i",
2471 ast_ctx(proto).file, ast_ctx(proto).line);
2475 /* we need the new parameter-names */
2476 for (i = 0; i < proto->expression.params_count; ++i)
2477 ast_value_set_name(proto->expression.params[i], var->expression.params[i]->name);
2485 parseerror(parser, "global `%s` already declared here: %s:%i",
2486 var->name, ast_ctx(old).file, ast_ctx(old).line);
2490 if (opts_standard == COMPILER_QCC &&
2491 (old = parser_find_field(parser, var->name)))
2493 parseerror(parser, "cannot declare a field and a global of the same name with -std=qcc");
2494 parseerror(parser, "global `%s` already declared here: %s:%i",
2495 var->name, ast_ctx(old).file, ast_ctx(old).line);
2502 else /* it's not a global */
2504 old = parser_find_local(parser, var->name, parser->blocklocal, &isparam);
2505 if (old && !isparam) {
2506 parseerror(parser, "local `%s` already declared here: %s:%i",
2507 var->name, ast_ctx(old).file, (int)ast_ctx(old).line);
2511 old = parser_find_local(parser, var->name, 0, &isparam);
2512 if (old && isparam) {
2513 if (parsewarning(parser, WARN_LOCAL_SHADOWS,
2514 "local `%s` is shadowing a parameter", var->name))
2516 parseerror(parser, "local `%s` already declared here: %s:%i",
2517 var->name, ast_ctx(old).file, (int)ast_ctx(old).line);
2521 if (opts_standard != COMPILER_GMQCC) {
2530 * Create the global/local, and deal with vector types.
2533 if (var->expression.vtype == TYPE_VECTOR)
2535 else if (var->expression.vtype == TYPE_FIELD &&
2536 var->expression.next->expression.vtype == TYPE_VECTOR)
2540 if (!create_vector_members(parser, var, ve)) {
2546 varent.name = util_strdup(var->name);
2547 varent.var = (ast_expression*)var;
2550 /* deal with global variables, fields, functions */
2551 if (var->expression.vtype == TYPE_FIELD) {
2552 if (!(retval = parser_t_fields_add(parser, varent)))
2555 for (i = 0; i < 3; ++i) {
2556 if (!(retval = parser_t_fields_add(parser, ve[i])))
2560 parser->fields_count -= i+1;
2566 if (!(retval = parser_t_globals_add(parser, varent)))
2569 for (i = 0; i < 3; ++i) {
2570 if (!(retval = parser_t_globals_add(parser, ve[i])))
2574 parser->globals_count -= i+1;
2580 if (!(retval = parser_t_locals_add(parser, varent)))
2582 if (!(retval = ast_block_locals_add(localblock, var))) {
2583 parser->locals_count--;
2587 for (i = 0; i < 3; ++i) {
2588 if (!(retval = parser_t_locals_add(parser, ve[i])))
2590 if (!(retval = ast_block_collect(localblock, ve[i].var)))
2592 ve[i].var = NULL; /* from here it's being collected in the block */
2595 parser->locals_count -= i+1;
2596 localblock->locals_count--;
2603 ve[0].name = ve[1].name = ve[2].name = NULL;
2604 ve[0].var = ve[1].var = ve[2].var = NULL;
2609 if (parser->tok == ';') {
2610 ast_delete(basetype);
2611 if (!parser_next(parser)) {
2612 parseerror(parser, "error after variable declaration");
2618 if (parser->tok == ',')
2621 if (!var || (!localblock && basetype->expression.vtype == TYPE_FIELD)) {
2622 parseerror(parser, "missing comma or semicolon while parsing variables");
2626 if (localblock && opts_standard == COMPILER_QCC) {
2627 if (parsewarning(parser, WARN_LOCAL_CONSTANTS,
2628 "initializing expression turns variable `%s` into a constant in this standard",
2635 if (parser->tok != '{') {
2636 if (parser->tok != '=') {
2637 parseerror(parser, "missing semicolon or initializer");
2641 if (!parser_next(parser)) {
2642 parseerror(parser, "error parsing initializer");
2647 if (parser->tok == '#') {
2651 parseerror(parser, "cannot declare builtins within functions");
2654 if (var->expression.vtype != TYPE_FUNCTION) {
2655 parseerror(parser, "unexpected builtin number, '%s' is not a function", var->name);
2658 if (!parser_next(parser)) {
2659 parseerror(parser, "expected builtin number");
2662 if (parser->tok != TOKEN_INTCONST) {
2663 parseerror(parser, "builtin number must be an integer constant");
2666 if (parser_token(parser)->constval.i <= 0) {
2667 parseerror(parser, "builtin number must be an integer greater than zero");
2671 func = ast_function_new(ast_ctx(var), var->name, var);
2673 parseerror(parser, "failed to allocate function for `%s`", var->name);
2676 if (!parser_t_functions_add(parser, func)) {
2677 parseerror(parser, "failed to allocate slot for function `%s`", var->name);
2678 ast_function_delete(func);
2679 var->constval.vfunc = NULL;
2683 func->builtin = -parser_token(parser)->constval.i;
2685 if (!parser_next(parser)) {
2686 parseerror(parser, "expected comma or semicolon");
2687 ast_function_delete(func);
2688 var->constval.vfunc = NULL;
2692 else if (parser->tok == '{' || parser->tok == '[')
2695 parseerror(parser, "cannot declare functions within functions");
2699 if (!parse_function_body(parser, var))
2701 ast_delete(basetype);
2704 ast_expression *cexp;
2707 cexp = parse_expression_leave(parser, true);
2711 cval = (ast_value*)cexp;
2712 if (!ast_istype(cval, ast_value) || !cval->isconst)
2713 parseerror(parser, "cannot initialize a global constant variable with a non-constant expression");
2716 var->isconst = true;
2717 if (cval->expression.vtype == TYPE_STRING)
2718 var->constval.vstring = parser_strdup(cval->constval.vstring);
2720 memcpy(&var->constval, &cval->constval, sizeof(var->constval));
2726 if (parser->tok == ',') {
2727 if (!parser_next(parser)) {
2728 parseerror(parser, "expected another variable");
2732 if (parser->tok != TOKEN_IDENT) {
2733 parseerror(parser, "expected another variable");
2736 var = ast_value_copy(basetype);
2738 ast_value_set_name(var, parser_tokval(parser));
2739 if (!parser_next(parser)) {
2740 parseerror(parser, "error parsing variable declaration");
2746 if (parser->tok != ';') {
2747 parseerror(parser, "missing semicolon after variables");
2751 if (!parser_next(parser)) {
2752 parseerror(parser, "parse error after variable declaration");
2756 ast_delete(basetype);
2760 if (cleanvar && var)
2762 ast_delete(basetype);
2766 ast_delete(basetype);
2767 if (cleanvar && var)
2769 if (varent.name) mem_d(varent.name);
2770 if (ve[0].name) mem_d(ve[0].name);
2771 if (ve[1].name) mem_d(ve[1].name);
2772 if (ve[2].name) mem_d(ve[2].name);
2773 if (ve[0].var) mem_d(ve[0].var);
2774 if (ve[1].var) mem_d(ve[1].var);
2775 if (ve[2].var) mem_d(ve[2].var);
2779 static bool parser_global_statement(parser_t *parser)
2781 if (parser->tok == TOKEN_TYPENAME || parser->tok == '.')
2783 return parse_variable(parser, NULL);
2785 else if (parser->tok == TOKEN_KEYWORD)
2787 /* handle 'var' and 'const' */
2790 else if (parser->tok == '$')
2792 if (!parser_next(parser)) {
2793 parseerror(parser, "parse error");
2799 parseerror(parser, "unexpected token: %s", parser->lex->tok.value);
2805 static parser_t *parser;
2809 parser = (parser_t*)mem_a(sizeof(parser_t));
2813 memset(parser, 0, sizeof(*parser));
2817 bool parser_compile(const char *filename)
2819 parser->lex = lex_open(filename);
2821 printf("failed to open file \"%s\"\n", filename);
2825 /* initial lexer/parser state */
2826 parser->lex->flags.noops = true;
2828 if (parser_next(parser))
2830 while (parser->tok != TOKEN_EOF && parser->tok < TOKEN_ERROR)
2832 if (!parser_global_statement(parser)) {
2833 if (parser->tok == TOKEN_EOF)
2834 parseerror(parser, "unexpected eof");
2835 else if (!parser->errors)
2836 parseerror(parser, "there have been errors, bailing out");
2837 lex_close(parser->lex);
2843 parseerror(parser, "parse error");
2844 lex_close(parser->lex);
2849 lex_close(parser->lex);
2852 return !parser->errors;
2855 void parser_cleanup()
2858 for (i = 0; i < parser->functions_count; ++i) {
2859 ast_delete(parser->functions[i]);
2861 for (i = 0; i < parser->imm_vector_count; ++i) {
2862 ast_delete(parser->imm_vector[i]);
2864 for (i = 0; i < parser->imm_string_count; ++i) {
2865 ast_delete(parser->imm_string[i]);
2867 for (i = 0; i < parser->imm_float_count; ++i) {
2868 ast_delete(parser->imm_float[i]);
2870 for (i = 0; i < parser->fields_count; ++i) {
2871 ast_delete(parser->fields[i].var);
2872 mem_d(parser->fields[i].name);
2874 for (i = 0; i < parser->globals_count; ++i) {
2875 ast_delete(parser->globals[i].var);
2876 mem_d(parser->globals[i].name);
2878 MEM_VECTOR_CLEAR(parser, functions);
2879 MEM_VECTOR_CLEAR(parser, imm_vector);
2880 MEM_VECTOR_CLEAR(parser, imm_string);
2881 MEM_VECTOR_CLEAR(parser, imm_float);
2882 MEM_VECTOR_CLEAR(parser, globals);
2883 MEM_VECTOR_CLEAR(parser, fields);
2884 MEM_VECTOR_CLEAR(parser, locals);
2889 static uint16_t progdefs_crc_sum(uint16_t old, const char *str)
2891 return util_crc16(old, str, strlen(str));
2894 static void progdefs_crc_file(const char *str)
2896 /* write to progdefs.h here */
2899 static uint16_t progdefs_crc_both(uint16_t old, const char *str)
2901 old = progdefs_crc_sum(old, str);
2902 progdefs_crc_file(str);
2906 static void generate_checksum(parser_t *parser)
2908 uint16_t crc = 0xFFFF;
2911 crc = progdefs_crc_both(crc, "\n/* file generated by qcc, do not modify */\n\ntypedef struct\n{");
2912 crc = progdefs_crc_sum(crc, "\tint\tpad[28];\n");
2914 progdefs_crc_file("\tint\tpad;\n");
2915 progdefs_crc_file("\tint\tofs_return[3];\n");
2916 progdefs_crc_file("\tint\tofs_parm0[3];\n");
2917 progdefs_crc_file("\tint\tofs_parm1[3];\n");
2918 progdefs_crc_file("\tint\tofs_parm2[3];\n");
2919 progdefs_crc_file("\tint\tofs_parm3[3];\n");
2920 progdefs_crc_file("\tint\tofs_parm4[3];\n");
2921 progdefs_crc_file("\tint\tofs_parm5[3];\n");
2922 progdefs_crc_file("\tint\tofs_parm6[3];\n");
2923 progdefs_crc_file("\tint\tofs_parm7[3];\n");
2925 for (i = 0; i < parser->crc_globals; ++i) {
2926 if (!ast_istype(parser->globals[i].var, ast_value))
2928 switch (parser->globals[i].var->expression.vtype) {
2929 case TYPE_FLOAT: crc = progdefs_crc_both(crc, "\tfloat\t"); break;
2930 case TYPE_VECTOR: crc = progdefs_crc_both(crc, "\tvec3_t\t"); break;
2931 case TYPE_STRING: crc = progdefs_crc_both(crc, "\tstring_t\t"); break;
2932 case TYPE_FUNCTION: crc = progdefs_crc_both(crc, "\tfunc_t\t"); break;
2934 crc = progdefs_crc_both(crc, "\tint\t");
2937 crc = progdefs_crc_both(crc, parser->globals[i].name);
2938 crc = progdefs_crc_both(crc, ";\n");
2940 crc = progdefs_crc_both(crc, "} globalvars_t;\n\ntypedef struct\n{\n");
2941 for (i = 0; i < parser->crc_fields; ++i) {
2942 if (!ast_istype(parser->fields[i].var, ast_value))
2944 switch (parser->fields[i].var->expression.next->expression.vtype) {
2945 case TYPE_FLOAT: crc = progdefs_crc_both(crc, "\tfloat\t"); break;
2946 case TYPE_VECTOR: crc = progdefs_crc_both(crc, "\tvec3_t\t"); break;
2947 case TYPE_STRING: crc = progdefs_crc_both(crc, "\tstring_t\t"); break;
2948 case TYPE_FUNCTION: crc = progdefs_crc_both(crc, "\tfunc_t\t"); break;
2950 crc = progdefs_crc_both(crc, "\tint\t");
2953 crc = progdefs_crc_both(crc, parser->fields[i].name);
2954 crc = progdefs_crc_both(crc, ";\n");
2956 crc = progdefs_crc_both(crc, "} entvars_t;\n\n");
2961 bool parser_finish(const char *output)
2967 if (!parser->errors)
2969 ir = ir_builder_new("gmqcc_out");
2971 printf("failed to allocate builder\n");
2975 for (i = 0; i < parser->fields_count; ++i) {
2978 if (!ast_istype(parser->fields[i].var, ast_value))
2980 field = (ast_value*)parser->fields[i].var;
2981 isconst = field->isconst;
2982 field->isconst = false;
2983 if (!ast_global_codegen((ast_value*)field, ir)) {
2984 printf("failed to generate field %s\n", field->name);
2985 ir_builder_delete(ir);
2990 ast_expression *subtype;
2991 field->isconst = true;
2992 subtype = field->expression.next;
2993 ifld = ir_builder_create_field(ir, field->name, subtype->expression.vtype);
2994 if (subtype->expression.vtype == TYPE_FIELD)
2995 ifld->fieldtype = subtype->expression.next->expression.vtype;
2996 else if (subtype->expression.vtype == TYPE_FUNCTION)
2997 ifld->outtype = subtype->expression.next->expression.vtype;
2998 (void)!ir_value_set_field(field->ir_v, ifld);
3001 for (i = 0; i < parser->globals_count; ++i) {
3003 if (!ast_istype(parser->globals[i].var, ast_value))
3005 asvalue = (ast_value*)(parser->globals[i].var);
3006 if (!asvalue->uses && !asvalue->isconst && asvalue->expression.vtype != TYPE_FUNCTION) {
3007 if (strcmp(asvalue->name, "end_sys_globals") &&
3008 strcmp(asvalue->name, "end_sys_fields"))
3010 retval = retval && !genwarning(ast_ctx(asvalue), WARN_UNUSED_VARIABLE,
3011 "unused global: `%s`", asvalue->name);
3014 if (!ast_global_codegen(asvalue, ir)) {
3015 printf("failed to generate global %s\n", parser->globals[i].name);
3016 ir_builder_delete(ir);
3020 for (i = 0; i < parser->imm_float_count; ++i) {
3021 if (!ast_global_codegen(parser->imm_float[i], ir)) {
3022 printf("failed to generate global %s\n", parser->imm_float[i]->name);
3023 ir_builder_delete(ir);
3027 for (i = 0; i < parser->imm_string_count; ++i) {
3028 if (!ast_global_codegen(parser->imm_string[i], ir)) {
3029 printf("failed to generate global %s\n", parser->imm_string[i]->name);
3030 ir_builder_delete(ir);
3034 for (i = 0; i < parser->imm_vector_count; ++i) {
3035 if (!ast_global_codegen(parser->imm_vector[i], ir)) {
3036 printf("failed to generate global %s\n", parser->imm_vector[i]->name);
3037 ir_builder_delete(ir);
3041 for (i = 0; i < parser->functions_count; ++i) {
3042 if (!ast_function_codegen(parser->functions[i], ir)) {
3043 printf("failed to generate function %s\n", parser->functions[i]->name);
3044 ir_builder_delete(ir);
3047 if (!ir_function_finalize(parser->functions[i]->ir_func)) {
3048 printf("failed to finalize function %s\n", parser->functions[i]->name);
3049 ir_builder_delete(ir);
3056 ir_builder_dump(ir, printf);
3058 generate_checksum(parser);
3060 if (!ir_builder_generate(ir, output)) {
3061 printf("*** failed to generate output file\n");
3062 ir_builder_delete(ir);
3067 ir_builder_delete(ir);
3071 printf("*** there were compile errors\n");