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;
26 ast_function *function;
27 MEM_VECTOR_MAKE(varentry_t, locals);
32 /* TYPE_FIELD -> parser_find_fields is used instead of find_var
33 * TODO: TYPE_VECTOR -> x, y and z are accepted in the gmqcc standard
34 * anything else: type error
39 MEM_VEC_FUNCTIONS(parser_t, varentry_t, globals)
40 MEM_VEC_FUNCTIONS(parser_t, varentry_t, fields)
41 MEM_VEC_FUNCTIONS(parser_t, ast_value*, imm_float)
42 MEM_VEC_FUNCTIONS(parser_t, ast_value*, imm_string)
43 MEM_VEC_FUNCTIONS(parser_t, ast_value*, imm_vector)
44 MEM_VEC_FUNCTIONS(parser_t, varentry_t, locals)
45 MEM_VEC_FUNCTIONS(parser_t, ast_function*, functions)
47 static bool GMQCC_WARN parser_pop_local(parser_t *parser);
48 static bool parse_variable(parser_t *parser, ast_block *localblock);
49 static ast_block* parse_block(parser_t *parser, bool warnreturn);
50 static bool parse_block_into(parser_t *parser, ast_block *block, bool warnreturn);
51 static ast_expression* parse_statement_or_block(parser_t *parser);
52 static ast_expression* parse_expression_leave(parser_t *parser, bool stopatcomma);
53 static ast_expression* parse_expression(parser_t *parser, bool stopatcomma);
55 static void parseerror(parser_t *parser, const char *fmt, ...)
62 vprintmsg(LVL_ERROR, parser->lex->tok.ctx.file, parser->lex->tok.ctx.line, "parse error", fmt, ap);
66 /* returns true if it counts as an error */
67 static bool GMQCC_WARN parsewarning(parser_t *parser, int warntype, const char *fmt, ...)
70 int lvl = LVL_WARNING;
72 if (!OPTS_WARN(warntype))
81 vprintmsg(lvl, parser->lex->tok.ctx.file, parser->lex->tok.ctx.line, "warning", fmt, ap);
87 static bool GMQCC_WARN genwarning(lex_ctx ctx, int warntype, const char *fmt, ...)
90 int lvl = LVL_WARNING;
92 if (!OPTS_WARN(warntype))
99 vprintmsg(lvl, ctx.file, ctx.line, "warning", fmt, ap);
105 /**********************************************************************
106 * some maths used for constant folding
109 vector vec3_add(vector a, vector b)
118 vector vec3_sub(vector a, vector b)
127 qcfloat vec3_mulvv(vector a, vector b)
129 return (a.x * b.x + a.y * b.y + a.z * b.z);
132 vector vec3_mulvf(vector a, float b)
141 /**********************************************************************
145 bool parser_next(parser_t *parser)
147 /* lex_do kills the previous token */
148 parser->tok = lex_do(parser->lex);
149 if (parser->tok == TOKEN_EOF)
151 if (parser->tok >= TOKEN_ERROR) {
152 parseerror(parser, "lex error");
158 #define parser_tokval(p) ((p)->lex->tok.value)
159 #define parser_token(p) (&((p)->lex->tok))
160 #define parser_ctx(p) ((p)->lex->tok.ctx)
162 static ast_value* parser_const_float(parser_t *parser, double d)
166 for (i = 0; i < parser->imm_float_count; ++i) {
167 if (parser->imm_float[i]->constval.vfloat == d)
168 return parser->imm_float[i];
170 out = ast_value_new(parser_ctx(parser), "#IMMEDIATE", TYPE_FLOAT);
172 out->constval.vfloat = d;
173 if (!parser_t_imm_float_add(parser, out)) {
174 ast_value_delete(out);
180 static ast_value* parser_const_float_0(parser_t *parser)
182 if (!parser->imm_float_zero)
183 parser->imm_float_zero = parser_const_float(parser, 0);
184 return parser->imm_float_zero;
187 static char *parser_strdup(const char *str)
190 /* actually dup empty strings */
191 char *out = mem_a(1);
195 return util_strdup(str);
198 static ast_value* parser_const_string(parser_t *parser, const char *str)
202 for (i = 0; i < parser->imm_string_count; ++i) {
203 if (!strcmp(parser->imm_string[i]->constval.vstring, str))
204 return parser->imm_string[i];
206 out = ast_value_new(parser_ctx(parser), "#IMMEDIATE", TYPE_STRING);
208 out->constval.vstring = parser_strdup(str);
209 if (!parser_t_imm_string_add(parser, out)) {
210 ast_value_delete(out);
216 static ast_value* parser_const_vector(parser_t *parser, vector v)
220 for (i = 0; i < parser->imm_vector_count; ++i) {
221 if (!memcmp(&parser->imm_vector[i]->constval.vvec, &v, sizeof(v)))
222 return parser->imm_vector[i];
224 out = ast_value_new(parser_ctx(parser), "#IMMEDIATE", TYPE_VECTOR);
226 out->constval.vvec = v;
227 if (!parser_t_imm_vector_add(parser, out)) {
228 ast_value_delete(out);
234 static ast_value* parser_const_vector_f(parser_t *parser, float x, float y, float z)
240 return parser_const_vector(parser, v);
243 static ast_value* parser_const_vector_0(parser_t *parser)
245 if (!parser->imm_vector_zero)
246 parser->imm_vector_zero = parser_const_vector_f(parser, 0, 0, 0);
247 return parser->imm_vector_zero;
250 static ast_expression* parser_find_field(parser_t *parser, const char *name)
253 for (i = 0; i < parser->fields_count; ++i) {
254 if (!strcmp(parser->fields[i].name, name))
255 return parser->fields[i].var;
260 static ast_expression* parser_find_global(parser_t *parser, const char *name)
263 for (i = 0; i < parser->globals_count; ++i) {
264 if (!strcmp(parser->globals[i].name, name))
265 return parser->globals[i].var;
270 static ast_expression* parser_find_param(parser_t *parser, const char *name)
274 if (!parser->function)
276 fun = parser->function->vtype;
277 for (i = 0; i < fun->expression.params_count; ++i) {
278 if (!strcmp(fun->expression.params[i]->name, name))
279 return (ast_expression*)(fun->expression.params[i]);
284 static ast_expression* parser_find_local(parser_t *parser, const char *name, size_t upto, bool *isparam)
288 for (i = parser->locals_count; i > upto;) {
290 if (!strcmp(parser->locals[i].name, name))
291 return parser->locals[i].var;
294 return parser_find_param(parser, name);
297 static ast_expression* parser_find_var(parser_t *parser, const char *name)
301 v = parser_find_local(parser, name, 0, &dummy);
302 if (!v) v = parser_find_global(parser, name);
307 MEM_VECTOR_MAKE(ast_value*, p);
309 MEM_VEC_FUNCTIONS(paramlist_t, ast_value*, p)
311 static ast_value *parse_type(parser_t *parser, int basetype, bool *isfunc)
315 lex_ctx ctx = parser_ctx(parser);
316 int vtype = basetype;
319 bool variadic = false;
321 MEM_VECTOR_INIT(¶ms, p);
325 if (parser->tok == '(') {
330 bool isfield = false;
331 bool isfuncparam = false;
333 if (!parser_next(parser))
336 if (parser->tok == ')')
339 if (parser->tok == '.') {
341 if (!parser_next(parser)) {
342 parseerror(parser, "expected field parameter type");
347 if (parser->tok == TOKEN_DOTS) {
350 if (!parser_next(parser))
352 if (parser->tok != ')') {
353 parseerror(parser, "`...` must be the last parameter of a variadic function declaration");
356 if (opts_standard == COMPILER_QCC) {
357 if (parsewarning(parser, WARN_EXTENSIONS, "variadic functions are not available in this standard"))
363 temptype = parser_token(parser)->constval.t;
364 if (!parser_next(parser))
367 param = parse_type(parser, temptype, &isfuncparam);
372 if (parser->tok == TOKEN_IDENT) {
373 /* named parameter */
374 if (!ast_value_set_name(param, parser_tokval(parser)))
376 if (!parser_next(parser))
380 /* This comes before the isfield part! */
382 ast_value *fval = ast_value_new(ast_ctx(param), param->name, TYPE_FUNCTION);
387 fval->expression.next = (ast_expression*)param;
388 MEM_VECTOR_MOVE(¶m->expression, params, &fval->expression, params);
389 fval->expression.variadic = param->expression.variadic;
394 fld = ast_value_new(ctx, param->name, TYPE_FIELD);
395 fld->expression.next = (ast_expression*)param;
399 if (!paramlist_t_p_add(¶ms, param)) {
400 parseerror(parser, "Out of memory while parsing typename");
404 if (parser->tok == ',')
406 if (parser->tok == ')')
408 parseerror(parser, "Unexpected token");
411 if (!parser_next(parser))
415 var = ast_value_new(ctx, "<unnamed>", vtype);
418 var->expression.variadic = variadic;
419 MEM_VECTOR_MOVE(¶ms, p, &var->expression, params);
422 for (i = 0; i < params.p_count; ++i)
423 ast_value_delete(params.p[i]);
424 MEM_VECTOR_CLEAR(¶ms, p);
430 size_t etype; /* 0 = expression, others are operators */
434 ast_block *block; /* for commas and function calls */
439 MEM_VECTOR_MAKE(sy_elem, out);
440 MEM_VECTOR_MAKE(sy_elem, ops);
442 MEM_VEC_FUNCTIONS(shunt, sy_elem, out)
443 MEM_VEC_FUNCTIONS(shunt, sy_elem, ops)
445 static sy_elem syexp(lex_ctx ctx, ast_expression *v) {
455 static sy_elem syblock(lex_ctx ctx, ast_block *v) {
458 e.out = (ast_expression*)v;
465 static sy_elem syop(lex_ctx ctx, const oper_info *op) {
467 e.etype = 1 + (op - operators);
475 static sy_elem syparen(lex_ctx ctx, int p, size_t off) {
487 # define DEBUGSHUNTDO(x) x
489 # define DEBUGSHUNTDO(x)
492 static bool parser_sy_pop(parser_t *parser, shunt *sy)
496 ast_expression *out = NULL;
497 ast_expression *exprs[3];
498 ast_block *blocks[3];
499 ast_value *asvalue[3];
501 qcint generated_op = 0;
503 if (!sy->ops_count) {
504 parseerror(parser, "internal error: missing operator");
508 if (sy->ops[sy->ops_count-1].paren) {
509 parseerror(parser, "unmatched parenthesis");
513 op = &operators[sy->ops[sy->ops_count-1].etype - 1];
514 ctx = sy->ops[sy->ops_count-1].ctx;
516 DEBUGSHUNTDO(printf("apply %s\n", op->op));
518 if (sy->out_count < op->operands) {
519 parseerror(parser, "internal error: not enough operands: %i (operator %s (%i))", sy->out_count,
520 op->op, (int)op->id);
526 sy->out_count -= op->operands;
527 for (i = 0; i < op->operands; ++i) {
528 exprs[i] = sy->out[sy->out_count+i].out;
529 blocks[i] = sy->out[sy->out_count+i].block;
530 asvalue[i] = (ast_value*)exprs[i];
533 if (blocks[0] && !blocks[0]->exprs_count && op->id != opid1(',')) {
534 parseerror(parser, "internal error: operator cannot be applied on empty blocks");
538 #define NotSameType(T) \
539 (exprs[0]->expression.vtype != exprs[1]->expression.vtype || \
540 exprs[0]->expression.vtype != T)
541 #define CanConstFold1(A) \
542 (ast_istype((A), ast_value) && ((ast_value*)(A))->isconst)
543 #define CanConstFold(A, B) \
544 (CanConstFold1(A) && CanConstFold1(B))
545 #define ConstV(i) (asvalue[(i)]->constval.vvec)
546 #define ConstF(i) (asvalue[(i)]->constval.vfloat)
547 #define ConstS(i) (asvalue[(i)]->constval.vstring)
551 parseerror(parser, "internal error: unhandled operator: %s (%i)", op->op, (int)op->id);
555 if (exprs[0]->expression.vtype == TYPE_ENTITY) {
556 if (exprs[1]->expression.vtype != TYPE_FIELD) {
557 parseerror(parser, "type error: right hand of member-operand should be an entity-field");
560 out = (ast_expression*)ast_entfield_new(ctx, exprs[0], exprs[1]);
562 else if (exprs[0]->expression.vtype == TYPE_VECTOR) {
563 parseerror(parser, "internal error: vector access is not supposed to be handled at this point");
567 parseerror(parser, "type error: member-of operator on something that is not an entity or vector");
574 if (!ast_block_exprs_add(blocks[0], exprs[1]))
577 blocks[0] = ast_block_new(ctx);
578 if (!ast_block_exprs_add(blocks[0], exprs[0]) ||
579 !ast_block_exprs_add(blocks[0], exprs[1]))
584 if (!ast_block_set_type(blocks[0], exprs[1]))
587 sy->out[sy->out_count++] = syblock(ctx, blocks[0]);
591 switch (exprs[0]->expression.vtype) {
593 if (CanConstFold1(exprs[0]))
594 out = (ast_expression*)parser_const_float(parser, -ConstF(0));
596 out = (ast_expression*)ast_binary_new(ctx, INSTR_SUB_F,
597 (ast_expression*)parser_const_float_0(parser),
601 if (CanConstFold1(exprs[0]))
602 out = (ast_expression*)parser_const_vector_f(parser,
603 -ConstV(0).x, -ConstV(0).y, -ConstV(0).z);
605 out = (ast_expression*)ast_binary_new(ctx, INSTR_SUB_V,
606 (ast_expression*)parser_const_vector_0(parser),
610 parseerror(parser, "invalid types used in expression: cannot negate type %s",
611 type_name[exprs[0]->expression.vtype]);
617 switch (exprs[0]->expression.vtype) {
619 if (CanConstFold1(exprs[0]))
620 out = (ast_expression*)parser_const_float(parser, !ConstF(0));
622 out = (ast_expression*)ast_unary_new(ctx, INSTR_NOT_F, exprs[0]);
625 if (CanConstFold1(exprs[0]))
626 out = (ast_expression*)parser_const_float(parser,
627 (!ConstV(0).x && !ConstV(0).y && !ConstV(0).z));
629 out = (ast_expression*)ast_unary_new(ctx, INSTR_NOT_V, exprs[0]);
632 if (CanConstFold1(exprs[0]))
633 out = (ast_expression*)parser_const_float(parser, !ConstS(0) || !*ConstS(0));
635 out = (ast_expression*)ast_unary_new(ctx, INSTR_NOT_S, exprs[0]);
637 /* we don't constant-fold NOT for these types */
639 out = (ast_expression*)ast_unary_new(ctx, INSTR_NOT_ENT, exprs[0]);
642 out = (ast_expression*)ast_unary_new(ctx, INSTR_NOT_FNC, exprs[0]);
645 parseerror(parser, "invalid types used in expression: cannot logically negate type %s",
646 type_name[exprs[0]->expression.vtype]);
652 if (exprs[0]->expression.vtype != exprs[1]->expression.vtype ||
653 (exprs[0]->expression.vtype != TYPE_VECTOR && exprs[0]->expression.vtype != TYPE_FLOAT) )
655 parseerror(parser, "invalid types used in expression: cannot add type %s and %s",
656 type_name[exprs[0]->expression.vtype],
657 type_name[exprs[1]->expression.vtype]);
660 switch (exprs[0]->expression.vtype) {
662 if (CanConstFold(exprs[0], exprs[1]))
664 out = (ast_expression*)parser_const_float(parser, ConstF(0) + ConstF(1));
667 out = (ast_expression*)ast_binary_new(ctx, INSTR_ADD_F, exprs[0], exprs[1]);
670 if (CanConstFold(exprs[0], exprs[1]))
671 out = (ast_expression*)parser_const_vector(parser, vec3_add(ConstV(0), ConstV(1)));
673 out = (ast_expression*)ast_binary_new(ctx, INSTR_ADD_V, exprs[0], exprs[1]);
676 parseerror(parser, "invalid types used in expression: cannot add type %s and %s",
677 type_name[exprs[0]->expression.vtype],
678 type_name[exprs[1]->expression.vtype]);
683 if (exprs[0]->expression.vtype != exprs[1]->expression.vtype ||
684 (exprs[0]->expression.vtype != TYPE_VECTOR && exprs[0]->expression.vtype != TYPE_FLOAT) )
686 parseerror(parser, "invalid types used in expression: cannot subtract type %s from %s",
687 type_name[exprs[1]->expression.vtype],
688 type_name[exprs[0]->expression.vtype]);
691 switch (exprs[0]->expression.vtype) {
693 if (CanConstFold(exprs[0], exprs[1]))
694 out = (ast_expression*)parser_const_float(parser, ConstF(0) - ConstF(1));
696 out = (ast_expression*)ast_binary_new(ctx, INSTR_SUB_F, exprs[0], exprs[1]);
699 if (CanConstFold(exprs[0], exprs[1]))
700 out = (ast_expression*)parser_const_vector(parser, vec3_sub(ConstV(0), ConstV(1)));
702 out = (ast_expression*)ast_binary_new(ctx, INSTR_SUB_V, exprs[0], exprs[1]);
705 parseerror(parser, "invalid types used in expression: cannot subtract type %s from %s",
706 type_name[exprs[1]->expression.vtype],
707 type_name[exprs[0]->expression.vtype]);
712 if (exprs[0]->expression.vtype != exprs[1]->expression.vtype &&
713 exprs[0]->expression.vtype != TYPE_VECTOR &&
714 exprs[0]->expression.vtype != TYPE_FLOAT &&
715 exprs[1]->expression.vtype != TYPE_VECTOR &&
716 exprs[1]->expression.vtype != TYPE_FLOAT)
718 parseerror(parser, "invalid types used in expression: cannot multiply types %s and %s",
719 type_name[exprs[1]->expression.vtype],
720 type_name[exprs[0]->expression.vtype]);
723 switch (exprs[0]->expression.vtype) {
725 if (exprs[1]->expression.vtype == TYPE_VECTOR)
727 if (CanConstFold(exprs[0], exprs[1]))
728 out = (ast_expression*)parser_const_vector(parser, vec3_mulvf(ConstV(1), ConstF(0)));
730 out = (ast_expression*)ast_binary_new(ctx, INSTR_MUL_FV, exprs[0], exprs[1]);
734 if (CanConstFold(exprs[0], exprs[1]))
735 out = (ast_expression*)parser_const_float(parser, ConstF(0) * ConstF(1));
737 out = (ast_expression*)ast_binary_new(ctx, INSTR_MUL_F, exprs[0], exprs[1]);
741 if (exprs[1]->expression.vtype == TYPE_FLOAT)
743 if (CanConstFold(exprs[0], exprs[1]))
744 out = (ast_expression*)parser_const_vector(parser, vec3_mulvf(ConstV(0), ConstF(1)));
746 out = (ast_expression*)ast_binary_new(ctx, INSTR_MUL_VF, exprs[0], exprs[1]);
750 if (CanConstFold(exprs[0], exprs[1]))
751 out = (ast_expression*)parser_const_float(parser, vec3_mulvv(ConstV(0), ConstV(1)));
753 out = (ast_expression*)ast_binary_new(ctx, INSTR_MUL_V, exprs[0], exprs[1]);
757 parseerror(parser, "invalid types used in expression: cannot multiply types %s and %s",
758 type_name[exprs[1]->expression.vtype],
759 type_name[exprs[0]->expression.vtype]);
764 if (NotSameType(TYPE_FLOAT)) {
765 parseerror(parser, "invalid types used in expression: cannot divide types %s and %s",
766 type_name[exprs[0]->expression.vtype],
767 type_name[exprs[1]->expression.vtype]);
770 if (CanConstFold(exprs[0], exprs[1]))
771 out = (ast_expression*)parser_const_float(parser, ConstF(0) / ConstF(1));
773 out = (ast_expression*)ast_binary_new(ctx, INSTR_DIV_F, exprs[0], exprs[1]);
777 parseerror(parser, "qc does not have a modulo operator");
781 if (NotSameType(TYPE_FLOAT)) {
782 parseerror(parser, "invalid types used in expression: cannot perform bit operations between types %s and %s",
783 type_name[exprs[0]->expression.vtype],
784 type_name[exprs[1]->expression.vtype]);
787 if (CanConstFold(exprs[0], exprs[1]))
788 out = (ast_expression*)parser_const_float(parser,
789 (op->id == opid1('|') ? (float)( ((qcint)ConstF(0)) | ((qcint)ConstF(1)) ) :
790 (float)( ((qcint)ConstF(0)) & ((qcint)ConstF(1)) ) ));
792 out = (ast_expression*)ast_binary_new(ctx,
793 (op->id == opid1('|') ? INSTR_BITOR : INSTR_BITAND),
797 parseerror(parser, "TODO: bitxor");
802 case opid3('<','<','='):
803 case opid3('>','>','='):
804 parseerror(parser, "TODO: shifts");
808 generated_op += 1; /* INSTR_OR */
810 generated_op += INSTR_AND;
811 if (NotSameType(TYPE_FLOAT)) {
812 parseerror(parser, "invalid types used in expression: cannot perform logical operations between types %s and %s",
813 type_name[exprs[0]->expression.vtype],
814 type_name[exprs[1]->expression.vtype]);
815 parseerror(parser, "TODO: logical ops for arbitrary types using INSTR_NOT");
816 parseerror(parser, "TODO: optional early out");
819 if (opts_standard == COMPILER_GMQCC)
820 printf("TODO: early out logic\n");
821 if (CanConstFold(exprs[0], exprs[1]))
822 out = (ast_expression*)parser_const_float(parser,
823 (generated_op == INSTR_OR ? (ConstF(0) || ConstF(1)) : (ConstF(0) && ConstF(1))));
825 out = (ast_expression*)ast_binary_new(ctx, generated_op, exprs[0], exprs[1]);
829 generated_op += 1; /* INSTR_GT */
831 generated_op += 1; /* INSTR_LT */
832 case opid2('>', '='):
833 generated_op += 1; /* INSTR_GE */
834 case opid2('<', '='):
835 generated_op += INSTR_LE;
836 if (NotSameType(TYPE_FLOAT)) {
837 parseerror(parser, "invalid types used in expression: cannot perform comparison between types %s and %s",
838 type_name[exprs[0]->expression.vtype],
839 type_name[exprs[1]->expression.vtype]);
842 out = (ast_expression*)ast_binary_new(ctx, generated_op, exprs[0], exprs[1]);
844 case opid2('!', '='):
845 if (exprs[0]->expression.vtype != exprs[1]->expression.vtype) {
846 parseerror(parser, "invalid types used in expression: cannot perform comparison between types %s and %s",
847 type_name[exprs[0]->expression.vtype],
848 type_name[exprs[1]->expression.vtype]);
851 out = (ast_expression*)ast_binary_new(ctx, type_ne_instr[exprs[0]->expression.vtype], exprs[0], exprs[1]);
853 case opid2('=', '='):
854 if (exprs[0]->expression.vtype != exprs[1]->expression.vtype) {
855 parseerror(parser, "invalid types used in expression: cannot perform comparison between types %s and %s",
856 type_name[exprs[0]->expression.vtype],
857 type_name[exprs[1]->expression.vtype]);
860 out = (ast_expression*)ast_binary_new(ctx, type_eq_instr[exprs[0]->expression.vtype], exprs[0], exprs[1]);
864 if (ast_istype(exprs[0], ast_entfield))
865 assignop = type_storep_instr[exprs[0]->expression.vtype];
867 assignop = type_store_instr[exprs[0]->expression.vtype];
868 out = (ast_expression*)ast_store_new(ctx, assignop, exprs[0], exprs[1]);
872 if (exprs[0]->expression.vtype != exprs[1]->expression.vtype ||
873 (exprs[0]->expression.vtype != TYPE_VECTOR && exprs[0]->expression.vtype != TYPE_FLOAT) )
875 parseerror(parser, "invalid types used in expression: cannot add or subtract type %s and %s",
876 type_name[exprs[0]->expression.vtype],
877 type_name[exprs[1]->expression.vtype]);
880 if (ast_istype(exprs[0], ast_entfield))
881 assignop = type_storep_instr[exprs[0]->expression.vtype];
883 assignop = type_store_instr[exprs[0]->expression.vtype];
884 switch (exprs[0]->expression.vtype) {
886 out = (ast_expression*)ast_binstore_new(ctx, assignop,
887 (op->id == opid2('+','=') ? INSTR_ADD_F : INSTR_SUB_F),
891 out = (ast_expression*)ast_binstore_new(ctx, assignop,
892 (op->id == opid2('+','=') ? INSTR_ADD_V : INSTR_SUB_V),
896 parseerror(parser, "invalid types used in expression: cannot add or subtract type %s and %s",
897 type_name[exprs[0]->expression.vtype],
898 type_name[exprs[1]->expression.vtype]);
906 parseerror(parser, "failed to apply operand %s", op->op);
910 DEBUGSHUNTDO(printf("applied %s\n", op->op));
911 sy->out[sy->out_count++] = syexp(ctx, out);
915 static bool parser_close_call(parser_t *parser, shunt *sy)
917 /* was a function call */
925 fid = sy->ops[sy->ops_count].off;
927 /* out[fid] is the function
928 * everything above is parameters...
930 * 1 params = ast_expression
934 if (sy->out_count < 1 || sy->out_count <= fid) {
935 parseerror(parser, "internal error: function call needs function and parameter list...");
939 fun = sy->out[fid].out;
941 call = ast_call_new(sy->ops[sy->ops_count].ctx, fun);
943 parseerror(parser, "out of memory");
947 if (fid+1 == sy->out_count) {
950 } else if (fid+2 == sy->out_count) {
953 params = sy->out[sy->out_count].block;
957 if (!ast_call_params_add(call, sy->out[sy->out_count].out)) {
958 ast_delete(sy->out[sy->out_count].out);
959 parseerror(parser, "out of memory");
963 paramcount = params->exprs_count;
964 MEM_VECTOR_MOVE(params, exprs, call, params);
968 parseerror(parser, "invalid function call");
972 /* overwrite fid, the function, with a call */
973 sy->out[fid] = syexp(call->expression.node.context, (ast_expression*)call);
975 if (fun->expression.vtype != TYPE_FUNCTION) {
976 parseerror(parser, "not a function (%s)", type_name[fun->expression.vtype]);
980 if (!fun->expression.next) {
981 parseerror(parser, "could not determine function return type");
984 if (fun->expression.params_count != paramcount &&
985 !(fun->expression.variadic &&
986 fun->expression.params_count < paramcount))
989 const char *fewmany = (fun->expression.params_count > paramcount) ? "few" : "many";
991 fval = (ast_istype(fun, ast_value) ? ((ast_value*)fun) : NULL);
992 if (opts_standard == COMPILER_GMQCC)
995 parseerror(parser, "too %s parameters for call to %s: expected %i, got %i\n"
996 " -> `%s` has been declared here: %s:%i",
997 fewmany, fval->name, (int)fun->expression.params_count, (int)paramcount,
998 fval->name, ast_ctx(fun).file, (int)ast_ctx(fun).line);
1000 parseerror(parser, "too %s parameters for function call: 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);
1009 return !parsewarning(parser, WARN_TOO_FEW_PARAMETERS,
1010 "too %s parameters for call to %s: expected %i, got %i\n"
1011 " -> `%s` has been declared here: %s:%i",
1012 fewmany, fval->name, (int)fun->expression.params_count, (int)paramcount,
1013 fval->name, ast_ctx(fun).file, (int)ast_ctx(fun).line);
1015 return !parsewarning(parser, WARN_TOO_FEW_PARAMETERS,
1016 "too %s parameters for function call: expected %i, got %i\n"
1017 " -> `%s` has been declared here: %s:%i",
1018 fewmany, fval->name, (int)fun->expression.params_count, (int)paramcount,
1019 fval->name, ast_ctx(fun).file, (int)ast_ctx(fun).line);
1027 static bool parser_close_paren(parser_t *parser, shunt *sy, bool functions_only)
1029 if (!sy->ops_count) {
1030 parseerror(parser, "unmatched closing paren");
1033 /* this would for bit a + (x) because there are no operators inside (x)
1034 if (sy->ops[sy->ops_count-1].paren == 1) {
1035 parseerror(parser, "empty parenthesis expression");
1039 while (sy->ops_count) {
1040 if (sy->ops[sy->ops_count-1].paren == 'f') {
1041 if (!parser_close_call(parser, sy))
1045 if (sy->ops[sy->ops_count-1].paren == 1) {
1047 return !functions_only;
1049 if (!parser_sy_pop(parser, sy))
1055 static void parser_reclassify_token(parser_t *parser)
1058 for (i = 0; i < operator_count; ++i) {
1059 if (!strcmp(parser_tokval(parser), operators[i].op)) {
1060 parser->tok = TOKEN_OPERATOR;
1066 static ast_expression* parse_expression_leave(parser_t *parser, bool stopatcomma)
1068 ast_expression *expr = NULL;
1070 bool wantop = false;
1071 bool gotmemberof = false;
1073 /* count the parens because an if starts with one, so the
1074 * end of a condition is an unmatched closing paren
1078 MEM_VECTOR_INIT(&sy, out);
1079 MEM_VECTOR_INIT(&sy, ops);
1081 parser->lex->flags.noops = false;
1083 parser_reclassify_token(parser);
1088 gotmemberof = false;
1090 parser->memberof = 0;
1092 if (parser->tok == TOKEN_IDENT)
1094 ast_expression *var;
1096 parseerror(parser, "expected operator or end of statement");
1101 if (opts_standard == COMPILER_GMQCC)
1103 if (parser->memberof == TYPE_ENTITY) {
1104 /* still get vars first since there could be a fieldpointer */
1105 var = parser_find_var(parser, parser_tokval(parser));
1107 var = parser_find_field(parser, parser_tokval(parser));
1109 else if (parser->memberof == TYPE_VECTOR)
1111 parseerror(parser, "TODO: implement effective vector member access");
1114 else if (parser->memberof) {
1115 parseerror(parser, "namespace for member not found");
1119 var = parser_find_var(parser, parser_tokval(parser));
1121 var = parser_find_var(parser, parser_tokval(parser));
1123 var = parser_find_field(parser, parser_tokval(parser));
1126 parseerror(parser, "unexpected ident: %s", parser_tokval(parser));
1129 if (ast_istype(var, ast_value))
1130 ((ast_value*)var)->uses++;
1131 if (!shunt_out_add(&sy, syexp(parser_ctx(parser), var))) {
1132 parseerror(parser, "out of memory");
1135 DEBUGSHUNTDO(printf("push %s\n", parser_tokval(parser)));
1137 else if (parser->tok == TOKEN_FLOATCONST) {
1140 parseerror(parser, "expected operator or end of statement, got constant");
1144 val = parser_const_float(parser, (parser_token(parser)->constval.f));
1147 if (!shunt_out_add(&sy, syexp(parser_ctx(parser), (ast_expression*)val))) {
1148 parseerror(parser, "out of memory");
1151 DEBUGSHUNTDO(printf("push %g\n", parser_token(parser)->constval.f));
1153 else if (parser->tok == TOKEN_INTCONST) {
1156 parseerror(parser, "expected operator or end of statement, got constant");
1160 val = parser_const_float(parser, (double)(parser_token(parser)->constval.i));
1163 if (!shunt_out_add(&sy, syexp(parser_ctx(parser), (ast_expression*)val))) {
1164 parseerror(parser, "out of memory");
1167 DEBUGSHUNTDO(printf("push %i\n", parser_token(parser)->constval.i));
1169 else if (parser->tok == TOKEN_STRINGCONST) {
1172 parseerror(parser, "expected operator or end of statement, got constant");
1176 val = parser_const_string(parser, parser_tokval(parser));
1179 if (!shunt_out_add(&sy, syexp(parser_ctx(parser), (ast_expression*)val))) {
1180 parseerror(parser, "out of memory");
1183 DEBUGSHUNTDO(printf("push string\n"));
1185 else if (parser->tok == TOKEN_VECTORCONST) {
1188 parseerror(parser, "expected operator or end of statement, got constant");
1192 val = parser_const_vector(parser, parser_token(parser)->constval.v);
1195 if (!shunt_out_add(&sy, syexp(parser_ctx(parser), (ast_expression*)val))) {
1196 parseerror(parser, "out of memory");
1199 DEBUGSHUNTDO(printf("push '%g %g %g'\n",
1200 parser_token(parser)->constval.v.x,
1201 parser_token(parser)->constval.v.y,
1202 parser_token(parser)->constval.v.z));
1204 else if (parser->tok == '(') {
1205 parseerror(parser, "internal error: '(' should be classified as operator");
1208 else if (parser->tok == ')') {
1210 DEBUGSHUNTDO(printf("do[op] )\n"));
1214 /* we do expect an operator next */
1215 /* closing an opening paren */
1216 if (!parser_close_paren(parser, &sy, false))
1219 DEBUGSHUNTDO(printf("do[nop] )\n"));
1223 /* allowed for function calls */
1224 if (!parser_close_paren(parser, &sy, true))
1229 else if (parser->tok != TOKEN_OPERATOR) {
1231 parseerror(parser, "expected operator or end of statement");
1238 /* classify the operator */
1239 /* TODO: suffix operators */
1240 const oper_info *op;
1241 const oper_info *olast = NULL;
1243 for (o = 0; o < operator_count; ++o) {
1244 if ((!(operators[o].flags & OP_PREFIX) == wantop) &&
1245 !(operators[o].flags & OP_SUFFIX) && /* remove this */
1246 !strcmp(parser_tokval(parser), operators[o].op))
1251 if (o == operator_count) {
1252 /* no operator found... must be the end of the statement */
1255 /* found an operator */
1258 /* when declaring variables, a comma starts a new variable */
1259 if (op->id == opid1(',') && !parens && stopatcomma) {
1260 /* fixup the token */
1265 if (sy.ops_count && !sy.ops[sy.ops_count-1].paren)
1266 olast = &operators[sy.ops[sy.ops_count-1].etype-1];
1269 (op->prec < olast->prec) ||
1270 (op->assoc == ASSOC_LEFT && op->prec <= olast->prec) ) )
1272 if (!parser_sy_pop(parser, &sy))
1274 if (sy.ops_count && !sy.ops[sy.ops_count-1].paren)
1275 olast = &operators[sy.ops[sy.ops_count-1].etype-1];
1280 if (op->id == opid1('.') && opts_standard == COMPILER_GMQCC) {
1281 /* for gmqcc standard: open up the namespace of the previous type */
1282 ast_expression *prevex = sy.out[sy.out_count-1].out;
1284 parseerror(parser, "unexpected member operator");
1287 if (prevex->expression.vtype == TYPE_ENTITY)
1288 parser->memberof = TYPE_ENTITY;
1289 else if (prevex->expression.vtype == TYPE_VECTOR)
1290 parser->memberof = TYPE_VECTOR;
1292 parseerror(parser, "type error: type has no members");
1298 if (op->id == opid1('(')) {
1300 DEBUGSHUNTDO(printf("push [op] (\n"));
1302 /* we expected an operator, this is the function-call operator */
1303 if (!shunt_ops_add(&sy, syparen(parser_ctx(parser), 'f', sy.out_count-1))) {
1304 parseerror(parser, "out of memory");
1309 if (!shunt_ops_add(&sy, syparen(parser_ctx(parser), 1, 0))) {
1310 parseerror(parser, "out of memory");
1313 DEBUGSHUNTDO(printf("push [nop] (\n"));
1317 DEBUGSHUNTDO(printf("push operator %s\n", op->op));
1318 if (!shunt_ops_add(&sy, syop(parser_ctx(parser), op)))
1323 if (!parser_next(parser)) {
1326 if (parser->tok == ';' || parser->tok == ']') {
1331 while (sy.ops_count) {
1332 if (!parser_sy_pop(parser, &sy))
1336 parser->lex->flags.noops = true;
1337 if (!sy.out_count) {
1338 parseerror(parser, "empty expression");
1341 expr = sy.out[0].out;
1342 MEM_VECTOR_CLEAR(&sy, out);
1343 MEM_VECTOR_CLEAR(&sy, ops);
1344 DEBUGSHUNTDO(printf("shunt done\n"));
1348 parser->lex->flags.noops = true;
1349 MEM_VECTOR_CLEAR(&sy, out);
1350 MEM_VECTOR_CLEAR(&sy, ops);
1354 static ast_expression* parse_expression(parser_t *parser, bool stopatcomma)
1356 ast_expression *e = parse_expression_leave(parser, stopatcomma);
1359 if (!parser_next(parser)) {
1366 static bool parse_if(parser_t *parser, ast_block *block, ast_expression **out)
1369 ast_expression *cond, *ontrue, *onfalse = NULL;
1371 lex_ctx ctx = parser_ctx(parser);
1373 /* skip the 'if' and check for opening paren */
1374 if (!parser_next(parser) || parser->tok != '(') {
1375 parseerror(parser, "expected 'if' condition in parenthesis");
1378 /* parse into the expression */
1379 if (!parser_next(parser)) {
1380 parseerror(parser, "expected 'if' condition after opening paren");
1383 /* parse the condition */
1384 cond = parse_expression_leave(parser, false);
1388 if (parser->tok != ')') {
1389 parseerror(parser, "expected closing paren after 'if' condition");
1393 /* parse into the 'then' branch */
1394 if (!parser_next(parser)) {
1395 parseerror(parser, "expected statement for on-true branch of 'if'");
1399 ontrue = parse_statement_or_block(parser);
1404 /* check for an else */
1405 if (!strcmp(parser_tokval(parser), "else")) {
1406 /* parse into the 'else' branch */
1407 if (!parser_next(parser)) {
1408 parseerror(parser, "expected on-false branch after 'else'");
1413 onfalse = parse_statement_or_block(parser);
1421 ifthen = ast_ifthen_new(ctx, cond, ontrue, onfalse);
1422 *out = (ast_expression*)ifthen;
1426 static bool parse_while(parser_t *parser, ast_block *block, ast_expression **out)
1429 ast_expression *cond, *ontrue;
1431 lex_ctx ctx = parser_ctx(parser);
1433 /* skip the 'while' and check for opening paren */
1434 if (!parser_next(parser) || parser->tok != '(') {
1435 parseerror(parser, "expected 'while' condition in parenthesis");
1438 /* parse into the expression */
1439 if (!parser_next(parser)) {
1440 parseerror(parser, "expected 'while' condition after opening paren");
1443 /* parse the condition */
1444 cond = parse_expression_leave(parser, false);
1448 if (parser->tok != ')') {
1449 parseerror(parser, "expected closing paren after 'while' condition");
1453 /* parse into the 'then' branch */
1454 if (!parser_next(parser)) {
1455 parseerror(parser, "expected while-loop body");
1459 ontrue = parse_statement_or_block(parser);
1465 aloop = ast_loop_new(ctx, NULL, cond, NULL, NULL, ontrue);
1466 *out = (ast_expression*)aloop;
1470 static bool parse_dowhile(parser_t *parser, ast_block *block, ast_expression **out)
1473 ast_expression *cond, *ontrue;
1475 lex_ctx ctx = parser_ctx(parser);
1477 /* skip the 'do' and get the body */
1478 if (!parser_next(parser)) {
1479 parseerror(parser, "expected loop body");
1482 ontrue = parse_statement_or_block(parser);
1486 /* expect the "while" */
1487 if (parser->tok != TOKEN_KEYWORD ||
1488 strcmp(parser_tokval(parser), "while"))
1490 parseerror(parser, "expected 'while' and condition");
1495 /* skip the 'while' and check for opening paren */
1496 if (!parser_next(parser) || parser->tok != '(') {
1497 parseerror(parser, "expected 'while' condition in parenthesis");
1501 /* parse into the expression */
1502 if (!parser_next(parser)) {
1503 parseerror(parser, "expected 'while' condition after opening paren");
1507 /* parse the condition */
1508 cond = parse_expression_leave(parser, false);
1512 if (parser->tok != ')') {
1513 parseerror(parser, "expected closing paren after 'while' condition");
1519 if (!parser_next(parser) || parser->tok != ';') {
1520 parseerror(parser, "expected semicolon after condition");
1526 if (!parser_next(parser)) {
1527 parseerror(parser, "parse error");
1533 aloop = ast_loop_new(ctx, NULL, NULL, cond, NULL, ontrue);
1534 *out = (ast_expression*)aloop;
1538 static bool parse_for(parser_t *parser, ast_block *block, ast_expression **out)
1541 ast_expression *initexpr, *cond, *increment, *ontrue;
1542 size_t oldblocklocal;
1545 lex_ctx ctx = parser_ctx(parser);
1547 oldblocklocal = parser->blocklocal;
1548 parser->blocklocal = parser->locals_count;
1555 /* skip the 'while' and check for opening paren */
1556 if (!parser_next(parser) || parser->tok != '(') {
1557 parseerror(parser, "expected 'for' expressions in parenthesis");
1560 /* parse into the expression */
1561 if (!parser_next(parser)) {
1562 parseerror(parser, "expected 'for' initializer after opening paren");
1566 if (parser->tok == TOKEN_TYPENAME) {
1567 if (opts_standard != COMPILER_GMQCC) {
1568 if (parsewarning(parser, WARN_EXTENSIONS,
1569 "current standard does not allow variable declarations in for-loop initializers"))
1573 parseerror(parser, "TODO: assignment of new variables to be non-const");
1575 if (!parse_variable(parser, block))
1578 else if (parser->tok != ';')
1580 initexpr = parse_expression_leave(parser, false);
1585 /* move on to condition */
1586 if (parser->tok != ';') {
1587 parseerror(parser, "expected semicolon after for-loop initializer");
1590 if (!parser_next(parser)) {
1591 parseerror(parser, "expected for-loop condition");
1595 /* parse the condition */
1596 if (parser->tok != ';') {
1597 cond = parse_expression_leave(parser, false);
1602 /* move on to incrementor */
1603 if (parser->tok != ';') {
1604 parseerror(parser, "expected semicolon after for-loop initializer");
1607 if (!parser_next(parser)) {
1608 parseerror(parser, "expected for-loop condition");
1612 /* parse the incrementor */
1613 if (parser->tok != ')') {
1614 increment = parse_expression_leave(parser, false);
1617 if (!ast_istype(increment, ast_store) &&
1618 !ast_istype(increment, ast_call) &&
1619 !ast_istype(increment, ast_binstore))
1621 if (genwarning(ast_ctx(increment), WARN_EFFECTLESS_STATEMENT, "statement has no effect"))
1627 if (parser->tok != ')') {
1628 parseerror(parser, "expected closing paren after 'for-loop' incrementor");
1631 /* parse into the 'then' branch */
1632 if (!parser_next(parser)) {
1633 parseerror(parser, "expected for-loop body");
1636 ontrue = parse_statement_or_block(parser);
1641 aloop = ast_loop_new(ctx, initexpr, cond, NULL, increment, ontrue);
1642 *out = (ast_expression*)aloop;
1644 while (parser->locals_count > parser->blocklocal)
1645 retval = retval && parser_pop_local(parser);
1646 parser->blocklocal = oldblocklocal;
1649 if (initexpr) ast_delete(initexpr);
1650 if (cond) ast_delete(cond);
1651 if (increment) ast_delete(increment);
1652 while (parser->locals_count > parser->blocklocal)
1653 (void)!parser_pop_local(parser);
1654 parser->blocklocal = oldblocklocal;
1658 static bool parse_statement(parser_t *parser, ast_block *block, ast_expression **out)
1660 if (parser->tok == TOKEN_TYPENAME)
1662 /* local variable */
1664 parseerror(parser, "cannot declare a variable from here");
1667 if (opts_standard == COMPILER_QCC) {
1668 if (parsewarning(parser, WARN_EXTENSIONS, "missing 'local' keyword when declaring a local variable"))
1671 if (!parse_variable(parser, block))
1676 else if (parser->tok == TOKEN_KEYWORD)
1678 if (!strcmp(parser_tokval(parser), "local"))
1681 parseerror(parser, "cannot declare a local variable here");
1684 if (!parser_next(parser)) {
1685 parseerror(parser, "expected variable declaration");
1688 if (!parse_variable(parser, block))
1693 else if (!strcmp(parser_tokval(parser), "return"))
1695 ast_expression *exp = NULL;
1696 ast_return *ret = NULL;
1697 ast_value *expected = parser->function->vtype;
1699 if (!parser_next(parser)) {
1700 parseerror(parser, "expected return expression");
1704 if (parser->tok != ';') {
1705 exp = parse_expression(parser, false);
1709 if (exp->expression.vtype != expected->expression.next->expression.vtype) {
1710 parseerror(parser, "return with invalid expression");
1713 ret = ast_return_new(exp->expression.node.context, exp);
1719 if (!parser_next(parser))
1720 parseerror(parser, "parse error");
1721 if (expected->expression.next->expression.vtype != TYPE_VOID) {
1722 if (opts_standard != COMPILER_GMQCC)
1723 (void)!parsewarning(parser, WARN_MISSING_RETURN_VALUES, "return without value");
1725 parseerror(parser, "return without value");
1727 ret = ast_return_new(parser_ctx(parser), NULL);
1729 *out = (ast_expression*)ret;
1732 else if (!strcmp(parser_tokval(parser), "if"))
1734 return parse_if(parser, block, out);
1736 else if (!strcmp(parser_tokval(parser), "while"))
1738 return parse_while(parser, block, out);
1740 else if (!strcmp(parser_tokval(parser), "do"))
1742 return parse_dowhile(parser, block, out);
1744 else if (!strcmp(parser_tokval(parser), "for"))
1746 if (opts_standard == COMPILER_QCC) {
1747 if (parsewarning(parser, WARN_EXTENSIONS, "for loops are not recognized in the original Quake C standard, to enable try an alternate standard --std=?"))
1750 return parse_for(parser, block, out);
1752 parseerror(parser, "Unexpected keyword");
1755 else if (parser->tok == '{')
1758 inner = parse_block(parser, false);
1761 *out = (ast_expression*)inner;
1766 ast_expression *exp = parse_expression(parser, false);
1770 if (!ast_istype(exp, ast_store) &&
1771 !ast_istype(exp, ast_call) &&
1772 !ast_istype(exp, ast_binstore))
1774 if (genwarning(ast_ctx(exp), WARN_EFFECTLESS_STATEMENT, "statement has no effect"))
1781 static bool GMQCC_WARN parser_pop_local(parser_t *parser)
1784 parser->locals_count--;
1786 ve = &parser->locals[parser->locals_count];
1787 if (ast_istype(ve->var, ast_value) && !(((ast_value*)(ve->var))->uses)) {
1788 if (parsewarning(parser, WARN_UNUSED_VARIABLE, "unused variable: `%s`", ve->name))
1791 mem_d(parser->locals[parser->locals_count].name);
1795 static bool parse_block_into(parser_t *parser, ast_block *block, bool warnreturn)
1797 size_t oldblocklocal;
1800 oldblocklocal = parser->blocklocal;
1801 parser->blocklocal = parser->locals_count;
1803 if (!parser_next(parser)) { /* skip the '{' */
1804 parseerror(parser, "expected function body");
1808 while (parser->tok != TOKEN_EOF && parser->tok < TOKEN_ERROR)
1810 ast_expression *expr;
1811 if (parser->tok == '}')
1814 if (!parse_statement(parser, block, &expr)) {
1815 parseerror(parser, "parse error");
1821 if (!ast_block_exprs_add(block, expr)) {
1828 if (parser->tok != '}') {
1831 if (warnreturn && parser->function->vtype->expression.next->expression.vtype != TYPE_VOID)
1833 if (!block->exprs_count ||
1834 !ast_istype(block->exprs[block->exprs_count-1], ast_return))
1836 if (parsewarning(parser, WARN_MISSING_RETURN_VALUES, "control reaches end of non-void function")) {
1842 (void)parser_next(parser);
1846 while (parser->locals_count > parser->blocklocal)
1847 retval = retval && parser_pop_local(parser);
1848 parser->blocklocal = oldblocklocal;
1852 static ast_block* parse_block(parser_t *parser, bool warnreturn)
1855 block = ast_block_new(parser_ctx(parser));
1858 if (!parse_block_into(parser, block, warnreturn)) {
1859 ast_block_delete(block);
1865 static ast_expression* parse_statement_or_block(parser_t *parser)
1867 ast_expression *expr = NULL;
1868 if (parser->tok == '{')
1869 return (ast_expression*)parse_block(parser, false);
1870 if (!parse_statement(parser, NULL, &expr))
1876 static bool create_vector_members(parser_t *parser, ast_value *var, varentry_t *ve)
1879 size_t len = strlen(var->name);
1881 for (i = 0; i < 3; ++i) {
1882 ve[i].var = (ast_expression*)ast_member_new(ast_ctx(var), (ast_expression*)var, i);
1886 ve[i].name = (char*)mem_a(len+3);
1888 ast_delete(ve[i].var);
1892 memcpy(ve[i].name, var->name, len);
1893 ve[i].name[len] = '_';
1894 ve[i].name[len+1] = 'x'+i;
1895 ve[i].name[len+2] = 0;
1904 ast_delete(ve[i].var);
1911 static bool parse_function_body(parser_t *parser, ast_value *var)
1913 ast_block *block = NULL;
1918 ast_expression *framenum = NULL;
1919 ast_expression *nextthink = NULL;
1920 /* None of the following have to be deleted */
1921 ast_expression *fld_think, *fld_nextthink, *fld_frame;
1922 ast_expression *gbl_time, *gbl_self;
1923 bool has_frame_think;
1927 has_frame_think = false;
1928 old = parser->function;
1930 if (var->expression.variadic) {
1931 if (parsewarning(parser, WARN_VARIADIC_FUNCTION,
1932 "variadic function with implementation will not be able to access additional parameters"))
1938 if (parser->tok == '[') {
1939 /* got a frame definition: [ framenum, nextthink ]
1940 * this translates to:
1941 * self.frame = framenum;
1942 * self.nextthink = time + 0.1;
1943 * self.think = nextthink;
1947 fld_think = parser_find_field(parser, "think");
1948 fld_nextthink = parser_find_field(parser, "nextthink");
1949 fld_frame = parser_find_field(parser, "frame");
1950 if (!fld_think || !fld_nextthink || !fld_frame) {
1951 parseerror(parser, "cannot use [frame,think] notation without the required fields");
1952 parseerror(parser, "please declare the following entityfields: `frame`, `think`, `nextthink`");
1955 gbl_time = parser_find_global(parser, "time");
1956 gbl_self = parser_find_global(parser, "self");
1957 if (!gbl_time || !gbl_self) {
1958 parseerror(parser, "cannot use [frame,think] notation without the required globals");
1959 parseerror(parser, "please declare the following globals: `time`, `self`");
1963 if (!parser_next(parser))
1966 framenum = parse_expression_leave(parser, true);
1968 parseerror(parser, "expected a framenumber constant in[frame,think] notation");
1971 if (!ast_istype(framenum, ast_value) || !( (ast_value*)framenum )->isconst) {
1972 ast_unref(framenum);
1973 parseerror(parser, "framenumber in [frame,think] notation must be a constant");
1977 if (parser->tok != ',') {
1978 ast_unref(framenum);
1979 parseerror(parser, "expected comma after frame number in [frame,think] notation");
1980 parseerror(parser, "Got a %i\n", parser->tok);
1984 if (!parser_next(parser)) {
1985 ast_unref(framenum);
1989 if (parser->tok == TOKEN_IDENT && !parser_find_var(parser, parser_tokval(parser)))
1991 /* qc allows the use of not-yet-declared functions here
1992 * - this automatically creates a prototype */
1994 ast_value *thinkfunc;
1995 ast_expression *functype = fld_think->expression.next;
1997 thinkfunc = ast_value_new(parser_ctx(parser), parser_tokval(parser), functype->expression.vtype);
1998 if (!thinkfunc || !ast_type_adopt(thinkfunc, functype)) {
1999 ast_unref(framenum);
2000 parseerror(parser, "failed to create implicit prototype for `%s`", parser_tokval(parser));
2004 if (!parser_next(parser)) {
2005 ast_unref(framenum);
2006 ast_delete(thinkfunc);
2010 varent.var = (ast_expression*)thinkfunc;
2011 varent.name = util_strdup(thinkfunc->name);
2012 if (!parser_t_globals_add(parser, varent)) {
2013 ast_unref(framenum);
2014 ast_delete(thinkfunc);
2017 nextthink = (ast_expression*)thinkfunc;
2020 nextthink = parse_expression_leave(parser, true);
2022 ast_unref(framenum);
2023 parseerror(parser, "expected a think-function in [frame,think] notation");
2028 if (!ast_istype(nextthink, ast_value)) {
2029 parseerror(parser, "think-function in [frame,think] notation must be a constant");
2033 if (retval && parser->tok != ']') {
2034 parseerror(parser, "expected closing `]` for [frame,think] notation");
2038 if (retval && !parser_next(parser)) {
2042 if (retval && parser->tok != '{') {
2043 parseerror(parser, "a function body has to be declared after a [frame,think] declaration");
2048 ast_unref(nextthink);
2049 ast_unref(framenum);
2053 has_frame_think = true;
2056 block = ast_block_new(parser_ctx(parser));
2058 parseerror(parser, "failed to allocate block");
2059 if (has_frame_think) {
2060 ast_unref(nextthink);
2061 ast_unref(framenum);
2066 if (has_frame_think) {
2068 ast_expression *self_frame;
2069 ast_expression *self_nextthink;
2070 ast_expression *self_think;
2071 ast_expression *time_plus_1;
2072 ast_store *store_frame;
2073 ast_store *store_nextthink;
2074 ast_store *store_think;
2076 ctx = parser_ctx(parser);
2077 self_frame = (ast_expression*)ast_entfield_new(ctx, gbl_self, fld_frame);
2078 self_nextthink = (ast_expression*)ast_entfield_new(ctx, gbl_self, fld_nextthink);
2079 self_think = (ast_expression*)ast_entfield_new(ctx, gbl_self, fld_think);
2081 time_plus_1 = (ast_expression*)ast_binary_new(ctx, INSTR_ADD_F,
2082 gbl_time, (ast_expression*)parser_const_float(parser, 0.1));
2084 if (!self_frame || !self_nextthink || !self_think || !time_plus_1) {
2085 if (self_frame) ast_delete(self_frame);
2086 if (self_nextthink) ast_delete(self_nextthink);
2087 if (self_think) ast_delete(self_think);
2088 if (time_plus_1) ast_delete(time_plus_1);
2094 store_frame = ast_store_new(ctx, INSTR_STOREP_F, self_frame, framenum);
2095 store_nextthink = ast_store_new(ctx, INSTR_STOREP_F, self_nextthink, time_plus_1);
2096 store_think = ast_store_new(ctx, INSTR_STOREP_FNC, self_think, nextthink);
2099 ast_delete(self_frame);
2102 if (!store_nextthink) {
2103 ast_delete(self_nextthink);
2107 ast_delete(self_think);
2111 if (store_frame) ast_delete(store_frame);
2112 if (store_nextthink) ast_delete(store_nextthink);
2113 if (store_think) ast_delete(store_think);
2116 if (retval && !ast_block_exprs_add(block, (ast_expression*)store_frame)) {
2117 ast_delete(store_frame);
2118 ast_delete(store_nextthink);
2119 ast_delete(store_think);
2123 if (retval && !ast_block_exprs_add(block, (ast_expression*)store_nextthink)) {
2124 ast_delete(store_nextthink);
2125 ast_delete(store_think);
2129 if (retval && !ast_block_exprs_add(block, (ast_expression*)store_think) )
2131 ast_delete(store_think);
2137 parseerror(parser, "failed to generate code for [frame,think]");
2138 ast_unref(nextthink);
2139 ast_unref(framenum);
2145 for (parami = 0; parami < var->expression.params_count; ++parami) {
2148 ast_value *param = var->expression.params[parami];
2150 if (param->expression.vtype != TYPE_VECTOR &&
2151 (param->expression.vtype != TYPE_FIELD ||
2152 param->expression.next->expression.vtype != TYPE_VECTOR))
2157 if (!create_vector_members(parser, param, ve)) {
2158 ast_block_delete(block);
2162 for (e = 0; e < 3; ++e) {
2163 if (!parser_t_locals_add(parser, ve[e]))
2165 if (!ast_block_collect(block, ve[e].var)) {
2166 parser->locals_count--;
2169 ve[e].var = NULL; /* collected */
2172 parser->locals -= e;
2177 ast_block_delete(block);
2182 func = ast_function_new(ast_ctx(var), var->name, var);
2184 parseerror(parser, "failed to allocate function for `%s`", var->name);
2185 ast_block_delete(block);
2188 if (!parser_t_functions_add(parser, func)) {
2189 parseerror(parser, "failed to allocate slot for function `%s`", var->name);
2190 ast_block_delete(block);
2194 parser->function = func;
2195 if (!parse_block_into(parser, block, true)) {
2196 ast_block_delete(block);
2200 if (!ast_function_blocks_add(func, block)) {
2201 ast_block_delete(block);
2205 parser->function = old;
2206 while (parser->locals_count)
2207 retval = retval && parser_pop_local(parser);
2209 if (parser->tok == ';')
2210 return parser_next(parser);
2211 else if (opts_standard == COMPILER_QCC)
2212 parseerror(parser, "missing semicolon after function body (mandatory with -std=qcc)");
2216 ast_function_delete(func);
2217 var->constval.vfunc = NULL;
2220 while (parser->locals_count) {
2221 parser->locals_count--;
2222 mem_d(parser->locals[parser->locals_count].name);
2224 parser->function = old;
2228 static bool parse_variable(parser_t *parser, ast_block *localblock)
2230 bool isfunc = false;
2233 ast_value *var = NULL;
2234 bool cleanvar = false;
2239 ast_expression *olddecl;
2250 int basetype = parser_token(parser)->constval.t;
2252 if (!parser_next(parser)) {
2253 parseerror(parser, "expected variable definition");
2257 typevar = parse_type(parser, basetype, &isfunc);
2268 ve[0].name = ve[1].name = ve[2].name = NULL;
2269 ve[0].var = ve[1].var = ve[2].var = NULL;
2271 ctx = parser_ctx(parser);
2272 var = ast_value_copy(typevar);
2276 parseerror(parser, "failed to create variable");
2281 if (parser->tok != TOKEN_IDENT) {
2282 parseerror(parser, "expected variable name");
2288 if (!localblock && (olddecl = parser_find_global(parser, parser_tokval(parser)))) {
2289 parseerror(parser, "global `%s` already declared here: %s:%i",
2290 parser_tokval(parser), ast_ctx(olddecl).file, (int)ast_ctx(olddecl).line);
2296 olddecl = parser_find_local(parser, parser_tokval(parser), parser->blocklocal, &isparam);
2297 if (opts_standard == COMPILER_GMQCC)
2302 parseerror(parser, "local `%s` already declared here: %s:%i",
2303 parser_tokval(parser), ast_ctx(olddecl).file, (int)ast_ctx(olddecl).line);
2309 if( (!isparam && olddecl) ||
2310 (olddecl = parser_find_local(parser, parser_tokval(parser), 0, &isparam))
2313 if (parsewarning(parser, WARN_LOCAL_SHADOWS,
2314 "local `%s` is shadowing a parameter", parser_tokval(parser)))
2316 parseerror(parser, "local `%s` already declared here: %s:%i",
2317 parser_tokval(parser), ast_ctx(olddecl).file, (int)ast_ctx(olddecl).line);
2327 ast_value_delete(var);
2330 parsewarning(parser, WARN_LOCAL_SHADOWS,
2331 "a parameter is shadowing local `%s`", parser_tokval(parser)))
2338 parseerror(parser, "local `%s` already declared here: %s:%i",
2339 parser_tokval(parser), ast_ctx(olddecl).file, (int)ast_ctx(olddecl).line);
2349 if (!ast_value_set_name(var, parser_tokval(parser))) {
2350 parseerror(parser, "failed to set variable name\n");
2356 /* a function was defined */
2358 ast_value *proto = NULL;
2362 olddecl = parser_find_global(parser, parser_tokval(parser));
2364 olddecl = parser_find_local(parser, parser_tokval(parser), parser->blocklocal, &dummy);
2367 /* we had a prototype */
2368 if (!ast_istype(olddecl, ast_value)) {
2372 parseerror(parser, "cannot declare a function with the same name as a vector's member: %s",
2373 parser_tokval(parser));
2378 proto = (ast_value*)olddecl;
2381 /* turn var into a value of TYPE_FUNCTION, with the old var
2384 fval = ast_value_new(ctx, var->name, TYPE_FUNCTION);
2390 fval->expression.next = (ast_expression*)var;
2391 MEM_VECTOR_MOVE(&var->expression, params, &fval->expression, params);
2392 fval->expression.variadic = var->expression.variadic;
2395 /* we compare the type late here, but it's easier than
2396 * messing with the parameter-vector etc. earlier
2400 if (!ast_compare_type((ast_expression*)proto, (ast_expression*)fval)) {
2401 parseerror(parser, "conflicting types for `%s`, previous declaration was here: %s:%i",
2403 ast_ctx(proto).file, ast_ctx(proto).line);
2404 ast_value_delete(fval);
2408 /* copy over the parameter names */
2409 for (param = 0; param < fval->expression.params_count; ++param)
2410 ast_value_set_name(proto->expression.params[param], fval->expression.params[param]->name);
2411 /* copy the new context */
2412 ast_ctx(proto) = ast_ctx(fval);
2414 /* now ditch the rest of the new data */
2415 ast_value_delete(fval);
2424 varent.name = util_strdup(var->name);
2425 varent.var = (ast_expression*)var;
2428 if (!(retval = parser_t_globals_add(parser, varent)))
2431 if (!(retval = parser_t_locals_add(parser, varent)))
2433 if (!(retval = ast_block_locals_add(localblock, var))) {
2434 parser->locals_count--;
2439 if (var->expression.vtype == TYPE_VECTOR)
2442 if (!create_vector_members(parser, var, ve)) {
2448 for (e = 0; e < 3; ++e) {
2449 if (!(retval = parser_t_globals_add(parser, ve[e])))
2453 parser->globals_count -= e+1;
2457 for (e = 0; e < 3; ++e) {
2458 if (!(retval = parser_t_locals_add(parser, ve[e])))
2460 if (!(retval = ast_block_collect(localblock, ve[e].var)))
2462 ve[e].var = NULL; /* from here it's being collected in the block */
2465 parser->locals_count -= e+1;
2466 localblock->locals_count--;
2470 ve[0].name = ve[1].name = ve[2].name = NULL;
2471 ve[0].var = ve[1].var = ve[2].var = NULL;
2478 if (!(retval = parser_next(parser)))
2481 if (parser->tok == ';') {
2482 ast_value_delete(typevar);
2483 return parser_next(parser);
2486 if (parser->tok == ',') {
2488 if (!(retval = parser_next(parser)))
2493 /* NOTE: only 'typevar' needs to be deleted from here on, so 'cleanup' won't be used
2494 * to avoid having too many gotos
2496 if (localblock && opts_standard == COMPILER_QCC) {
2497 if (parsewarning(parser, WARN_LOCAL_CONSTANTS,
2498 "initializing expression turns variable `%s` into a constant in this standard",
2501 ast_value_delete(typevar);
2506 if (parser->tok != '=') {
2507 if (opts_standard == COMPILER_QCC)
2508 parseerror(parser, "missing semicolon");
2510 parseerror(parser, "missing semicolon or initializer");
2511 ast_value_delete(typevar);
2515 if (!parser_next(parser)) {
2516 ast_value_delete(typevar);
2520 if (parser->tok == '#') {
2524 parseerror(parser, "cannot declare builtins within functions");
2525 ast_value_delete(typevar);
2529 parseerror(parser, "unexpected builtin number, '%s' is not a function", var->name);
2530 ast_value_delete(typevar);
2533 if (!parser_next(parser)) {
2534 parseerror(parser, "expected builtin number");
2535 ast_value_delete(typevar);
2538 if (parser->tok != TOKEN_INTCONST) {
2539 parseerror(parser, "builtin number must be an integer constant");
2540 ast_value_delete(typevar);
2543 if (parser_token(parser)->constval.i <= 0) {
2544 parseerror(parser, "builtin number must be positive integer greater than zero");
2545 ast_value_delete(typevar);
2549 func = ast_function_new(ast_ctx(var), var->name, var);
2551 parseerror(parser, "failed to allocate function for `%s`", var->name);
2552 ast_value_delete(typevar);
2555 if (!parser_t_functions_add(parser, func)) {
2556 parseerror(parser, "failed to allocate slot for function `%s`", var->name);
2557 ast_function_delete(func);
2558 var->constval.vfunc = NULL;
2559 ast_value_delete(typevar);
2563 func->builtin = -parser_token(parser)->constval.i;
2565 if (!parser_next(parser)) {
2566 ast_value_delete(typevar);
2570 else if (parser->tok == '{' || parser->tok == '[')
2572 ast_value_delete(typevar);
2574 parseerror(parser, "cannot declare functions within functions");
2578 if (!parse_function_body(parser, var)) {
2583 ast_expression *cexp;
2586 cexp = parse_expression_leave(parser, true);
2588 ast_value_delete(typevar);
2592 cval = (ast_value*)cexp;
2593 if (!ast_istype(cval, ast_value) || !cval->isconst)
2594 parseerror(parser, "cannot initialize a global constant variable with a non-constant expression");
2597 var->isconst = true;
2598 if (cval->expression.vtype == TYPE_STRING)
2599 var->constval.vstring = parser_strdup(cval->constval.vstring);
2601 memcpy(&var->constval, &cval->constval, sizeof(var->constval));
2606 if (parser->tok == ',') {
2611 if (parser->tok != ';') {
2612 parseerror(parser, "missing semicolon");
2613 ast_value_delete(typevar);
2617 (void)parser_next(parser);
2619 ast_value_delete(typevar);
2624 ast_delete(typevar);
2625 if (var && cleanvar) ast_delete(var);
2626 if (varent.name) mem_d(varent.name);
2627 if (ve[0].name) mem_d(ve[0].name);
2628 if (ve[1].name) mem_d(ve[1].name);
2629 if (ve[2].name) mem_d(ve[2].name);
2630 if (ve[0].var) mem_d(ve[0].var);
2631 if (ve[1].var) mem_d(ve[1].var);
2632 if (ve[2].var) mem_d(ve[2].var);
2637 static bool parser_global_statement(parser_t *parser)
2639 if (parser->tok == TOKEN_TYPENAME)
2641 return parse_variable(parser, NULL);
2643 else if (parser->tok == TOKEN_KEYWORD)
2645 /* handle 'var' and 'const' */
2648 else if (parser->tok == '.')
2653 ast_expression *oldex;
2654 bool isfunc = false;
2656 lex_ctx ctx = parser_ctx(parser);
2659 /* entity-member declaration */
2660 if (!parser_next(parser) || parser->tok != TOKEN_TYPENAME) {
2661 parseerror(parser, "expected member variable definition");
2665 /* remember the base/return type */
2666 basetype = parser_token(parser)->constval.t;
2668 /* parse into the declaration */
2669 if (!parser_next(parser)) {
2670 parseerror(parser, "expected field definition");
2674 /* parse the field type fully */
2675 typevar = var = parse_type(parser, basetype, &isfunc);
2680 var = ast_value_copy(typevar);
2681 /* now the field name */
2682 if (parser->tok != TOKEN_IDENT) {
2683 parseerror(parser, "expected field name");
2688 /* check for an existing field
2689 * in original qc we also have to check for an existing
2690 * global named like the field
2692 if (opts_standard == COMPILER_QCC) {
2693 if (parser_find_global(parser, parser_tokval(parser))) {
2694 parseerror(parser, "cannot declare a field and a global of the same name with -std=qcc");
2702 fval = ast_value_new(ctx, var->name, TYPE_FUNCTION);
2704 ast_value_delete(var);
2707 fval->expression.next = (ast_expression*)var;
2708 MEM_VECTOR_MOVE(&var->expression, params, &fval->expression, params);
2709 fval->expression.variadic = var->expression.variadic;
2713 /* turn it into a field */
2714 fld = ast_value_new(ctx, parser_tokval(parser), TYPE_FIELD);
2715 fld->expression.next = (ast_expression*)var;
2717 if ( (oldex = parser_find_field(parser, parser_tokval(parser)))) {
2718 if (ast_istype(oldex, ast_member)) {
2719 parseerror(parser, "cannot declare a field with the same name as a vector component, component %s has been declared here: %s:%i",
2720 parser_tokval(parser), ast_ctx(oldex).file, (int)ast_ctx(oldex).line);
2724 if (!ast_istype(oldex, ast_value)) {
2725 /* not possible / sanity check */
2726 parseerror(parser, "internal error: %s is not an ast_value", parser_tokval(parser));
2731 if (!ast_compare_type(oldex, (ast_expression*)fld)) {
2732 parseerror(parser, "field %s has previously been declared with a different type here: %s:%i",
2733 parser_tokval(parser), ast_ctx(oldex).file, (int)ast_ctx(oldex).line);
2737 if (parsewarning(parser, WARN_FIELD_REDECLARED, "field `%s` has already been declared here: %s:%i",
2738 parser_tokval(parser), ast_ctx(oldex).file, (int)ast_ctx(oldex).line))
2749 varent.var = (ast_expression*)fld;
2750 varent.name = util_strdup(fld->name);
2751 (void)!parser_t_fields_add(parser, varent);
2753 if (var->expression.vtype == TYPE_VECTOR)
2755 /* create _x, _y and _z fields as well */
2757 if (!create_vector_members(parser, fld, ve)) {
2761 (void)!parser_t_fields_add(parser, ve[0]);
2762 (void)!parser_t_fields_add(parser, ve[1]);
2763 (void)!parser_t_fields_add(parser, ve[2]);
2767 if (!parser_next(parser)) {
2768 parseerror(parser, "expected semicolon or another field name");
2771 if (parser->tok == ';')
2773 if (parser->tok != ',' || !parser_next(parser)) {
2774 parseerror(parser, "expected semicolon or another field name");
2778 ast_delete(typevar);
2780 /* skip the semicolon */
2781 if (!parser_next(parser))
2782 return parser->tok == TOKEN_EOF;
2786 else if (parser->tok == '$')
2788 if (!parser_next(parser)) {
2789 parseerror(parser, "parse error");
2795 parseerror(parser, "unexpected token: %s", parser->lex->tok.value);
2801 static parser_t *parser;
2805 parser = (parser_t*)mem_a(sizeof(parser_t));
2809 memset(parser, 0, sizeof(*parser));
2813 bool parser_compile(const char *filename)
2815 parser->lex = lex_open(filename);
2817 printf("failed to open file \"%s\"\n", filename);
2821 /* initial lexer/parser state */
2822 parser->lex->flags.noops = true;
2824 if (parser_next(parser))
2826 while (parser->tok != TOKEN_EOF && parser->tok < TOKEN_ERROR)
2828 if (!parser_global_statement(parser)) {
2829 if (parser->tok == TOKEN_EOF)
2830 parseerror(parser, "unexpected eof");
2831 else if (!parser->errors)
2832 parseerror(parser, "parse error");
2833 lex_close(parser->lex);
2839 parseerror(parser, "parse error");
2840 lex_close(parser->lex);
2845 lex_close(parser->lex);
2848 return !parser->errors;
2851 void parser_cleanup()
2854 for (i = 0; i < parser->functions_count; ++i) {
2855 ast_delete(parser->functions[i]);
2857 for (i = 0; i < parser->imm_vector_count; ++i) {
2858 ast_delete(parser->imm_vector[i]);
2860 for (i = 0; i < parser->imm_string_count; ++i) {
2861 ast_delete(parser->imm_string[i]);
2863 for (i = 0; i < parser->imm_float_count; ++i) {
2864 ast_delete(parser->imm_float[i]);
2866 for (i = 0; i < parser->fields_count; ++i) {
2867 ast_delete(parser->fields[i].var);
2868 mem_d(parser->fields[i].name);
2870 for (i = 0; i < parser->globals_count; ++i) {
2871 ast_delete(parser->globals[i].var);
2872 mem_d(parser->globals[i].name);
2874 MEM_VECTOR_CLEAR(parser, functions);
2875 MEM_VECTOR_CLEAR(parser, imm_vector);
2876 MEM_VECTOR_CLEAR(parser, imm_string);
2877 MEM_VECTOR_CLEAR(parser, imm_float);
2878 MEM_VECTOR_CLEAR(parser, globals);
2879 MEM_VECTOR_CLEAR(parser, fields);
2880 MEM_VECTOR_CLEAR(parser, locals);
2885 bool parser_finish(const char *output)
2891 if (!parser->errors)
2893 ir = ir_builder_new("gmqcc_out");
2895 printf("failed to allocate builder\n");
2899 for (i = 0; i < parser->fields_count; ++i) {
2902 if (!ast_istype(parser->fields[i].var, ast_value))
2904 field = (ast_value*)parser->fields[i].var;
2905 isconst = field->isconst;
2906 field->isconst = false;
2907 if (!ast_global_codegen((ast_value*)field, ir)) {
2908 printf("failed to generate field %s\n", field->name);
2909 ir_builder_delete(ir);
2914 ast_expression *subtype;
2915 field->isconst = true;
2916 subtype = field->expression.next;
2917 ifld = ir_builder_create_field(ir, field->name, subtype->expression.vtype);
2918 if (subtype->expression.vtype == TYPE_FIELD)
2919 ifld->fieldtype = subtype->expression.next->expression.vtype;
2920 else if (subtype->expression.vtype == TYPE_FUNCTION)
2921 ifld->outtype = subtype->expression.next->expression.vtype;
2922 (void)!ir_value_set_field(field->ir_v, ifld);
2925 for (i = 0; i < parser->globals_count; ++i) {
2927 if (!ast_istype(parser->globals[i].var, ast_value))
2929 asvalue = (ast_value*)(parser->globals[i].var);
2930 if (!asvalue->uses && !asvalue->isconst && asvalue->expression.vtype != TYPE_FUNCTION) {
2931 retval = retval && !genwarning(ast_ctx(asvalue), WARN_UNUSED_VARIABLE,
2932 "unused global: `%s`", asvalue->name);
2934 if (!ast_global_codegen(asvalue, ir)) {
2935 printf("failed to generate global %s\n", parser->globals[i].name);
2936 ir_builder_delete(ir);
2940 for (i = 0; i < parser->imm_float_count; ++i) {
2941 if (!ast_global_codegen(parser->imm_float[i], ir)) {
2942 printf("failed to generate global %s\n", parser->imm_float[i]->name);
2943 ir_builder_delete(ir);
2947 for (i = 0; i < parser->imm_string_count; ++i) {
2948 if (!ast_global_codegen(parser->imm_string[i], ir)) {
2949 printf("failed to generate global %s\n", parser->imm_string[i]->name);
2950 ir_builder_delete(ir);
2954 for (i = 0; i < parser->imm_vector_count; ++i) {
2955 if (!ast_global_codegen(parser->imm_vector[i], ir)) {
2956 printf("failed to generate global %s\n", parser->imm_vector[i]->name);
2957 ir_builder_delete(ir);
2961 for (i = 0; i < parser->functions_count; ++i) {
2962 if (!ast_function_codegen(parser->functions[i], ir)) {
2963 printf("failed to generate function %s\n", parser->functions[i]->name);
2964 ir_builder_delete(ir);
2967 if (!ir_function_finalize(parser->functions[i]->ir_func)) {
2968 printf("failed to finalize function %s\n", parser->functions[i]->name);
2969 ir_builder_delete(ir);
2976 ir_builder_dump(ir, printf);
2978 if (!ir_builder_generate(ir, output)) {
2979 printf("*** failed to generate output file\n");
2980 ir_builder_delete(ir);
2985 ir_builder_delete(ir);
2989 printf("*** there were compile errors\n");