ast_node_init((ast_node*)self, ctx, TYPE_##T); \
( (ast_node*)self )->node.destroy = (ast_node_delete*)destroyfn
+/* error handling */
+static void asterror(lex_ctx ctx, const char *msg, ...)
+{
+ va_list ap;
+ va_start(ap, msg);
+ cvprintmsg(ctx, LVL_ERROR, "error", msg, ap);
+ va_end(ap);
+}
+
/* It must not be possible to get here. */
static GMQCC_NORETURN void _ast_node_destroy(ast_node *self)
{
}
}
+bool ast_compare_type(ast_expression *a, ast_expression *b)
+{
+ if (a->expression.vtype != b->expression.vtype)
+ return false;
+ if (!a->expression.next != !b->expression.next)
+ return false;
+ if (a->expression.params_count != b->expression.params_count)
+ return false;
+ if (a->expression.params_count) {
+ size_t i;
+ for (i = 0; i < a->expression.params_count; ++i) {
+ if (!ast_compare_type((ast_expression*)a->expression.params[i],
+ (ast_expression*)b->expression.params[i]))
+ return false;
+ }
+ }
+ if (a->expression.next)
+ return ast_compare_type(a->expression.next, b->expression.next);
+ return true;
+}
+
ast_value* ast_value_new(lex_ctx ctx, const char *name, int t)
{
ast_instantiate(ast_value, ctx, ast_value_delete);
if (owner->expression.vtype != TYPE_VECTOR &&
owner->expression.vtype != TYPE_FIELD) {
- printf("ast_member on an invalid owner of type %i\n", (int)owner->expression.vtype);
+ asterror(ctx, "member-access on an invalid owner of type %s\n", type_name[owner->expression.vtype]);
mem_d(self);
return NULL;
}
* on all the globals.
*/
if (!self->ir_v) {
- printf("ast_value used before generated (%s)\n", self->name);
+ asterror(ast_ctx(self), "ast_value used before generated (%s)\n", self->name);
return false;
}
*out = self->ir_v;
if (!v)
return false;
if (self->isconst) {
- printf("TODO: constant field pointers with value\n");
+ asterror(ast_ctx(self), "TODO: constant field pointers with value\n");
goto error;
}
self->ir_v = v;
v = ir_builder_create_global(ir, self->name, self->expression.vtype);
if (!v) {
- printf("ir_builder_create_global failed\n");
+ asterror(ast_ctx(self), "ir_builder_create_global failed\n");
return false;
}
goto error;
break;
case TYPE_FUNCTION:
- printf("global of type function not properly generated\n");
+ asterror(ast_ctx(self), "global of type function not properly generated\n");
goto error;
/* Cannot generate an IR value for a function,
* need a pointer pointing to a function rather.
*/
default:
- printf("TODO: global constant type %i\n", self->expression.vtype);
+ asterror(ast_ctx(self), "TODO: global constant type %i\n", self->expression.vtype);
break;
}
}
goto error;
break;
default:
- printf("TODO: global constant type %i\n", self->expression.vtype);
+ asterror(ast_ctx(self), "TODO: global constant type %i\n", self->expression.vtype);
break;
}
}
irf = self->ir_func;
if (!irf) {
- printf("ast_function's related ast_value was not generated yet\n");
+ asterror(ast_ctx(self), "ast_function's related ast_value was not generated yet\n");
return false;
}
/* for a binstore we need both an lvalue and an rvalue for the left side */
/* rvalue of destination! */
cgen = self->dest->expression.codegen;
- if (!(*cgen)((ast_expression*)(self->dest), func, true, &leftr))
+ if (!(*cgen)((ast_expression*)(self->dest), func, false, &leftr))
return false;
/* source as rvalue only */
*/
(void)lvalue;
if (self->expression.outr) {
- printf("internal error: ast_return cannot be reused, it bears no result!\n");
+ asterror(ast_ctx(self), "internal error: ast_return cannot be reused, it bears no result!\n");
return false;
}
self->expression.outr = (ir_value*)1;
(void)lvalue;
if (self->expression.outr) {
- printf("internal error: ast_ifthen cannot be reused, it bears no result!\n");
+ asterror(ast_ctx(self), "internal error: ast_ifthen cannot be reused, it bears no result!\n");
return false;
}
self->expression.outr = (ir_value*)1;
(void)out;
if (self->expression.outr) {
- printf("internal error: ast_loop cannot be reused, it bears no result!\n");
+ asterror(ast_ctx(self), "internal error: ast_loop cannot be reused, it bears no result!\n");
return false;
}
self->expression.outr = (ir_value*)1;