ast_value *cp = ast_value_new(self->expression.node.context, self->name, self->expression.vtype);
if (self->expression.next) {
cp->expression.next = ast_type_copy(self->expression.node.context, self->expression.next);
- if (!cp->expression.next) {
- ast_value_delete(cp);
- return NULL;
- }
}
fromex = &self->expression;
selfex = &cp->expression;
selfex->flags = fromex->flags;
for (i = 0; i < vec_size(fromex->params); ++i) {
ast_value *v = ast_value_copy(fromex->params[i]);
- if (!v) {
- ast_value_delete(cp);
- return NULL;
- }
vec_push(selfex->params, v);
}
return cp;
}
-bool ast_type_adopt_impl(ast_expression *self, const ast_expression *other)
+void ast_type_adopt_impl(ast_expression *self, const ast_expression *other)
{
size_t i;
const ast_expression_common *fromex;
self->expression.vtype = other->expression.vtype;
if (other->expression.next) {
self->expression.next = (ast_expression*)ast_type_copy(ast_ctx(self), other->expression.next);
- if (!self->expression.next)
- return false;
}
fromex = &other->expression;
selfex = &self->expression;
selfex->flags = fromex->flags;
for (i = 0; i < vec_size(fromex->params); ++i) {
ast_value *v = ast_value_copy(fromex->params[i]);
- if (!v)
- return false;
vec_push(selfex->params, v);
}
- return true;
}
static ast_expression* ast_shallow_type(lex_ctx ctx, int vtype)
selfex->vtype = fromex->vtype;
if (fromex->next)
- {
selfex->next = ast_type_copy(ctx, fromex->next);
- if (!selfex->next) {
- ast_expression_delete_full(self);
- return NULL;
- }
- }
else
selfex->next = NULL;
selfex->flags = fromex->flags;
for (i = 0; i < vec_size(fromex->params); ++i) {
ast_value *v = ast_value_copy(fromex->params[i]);
- if (!v) {
- ast_expression_delete_full(self);
- return NULL;
- }
vec_push(selfex->params, v);
}
else
self->expression.vtype = left->expression.vtype;
+ /* references all */
+ self->refs = AST_REF_ALL;
+
return self;
}
void ast_binary_delete(ast_binary *self)
{
- ast_unref(self->left);
- ast_unref(self->right);
+ if (self->refs & AST_REF_LEFT) ast_unref(self->left);
+ if (self->refs & AST_REF_RIGHT) ast_unref(self->right);
+
ast_expression_delete((ast_expression*)self);
mem_d(self);
}
self->keep_dest = false;
- if (!ast_type_adopt(self, left)) {
- ast_delete(self);
- return NULL;
- }
-
+ ast_type_adopt(self, left);
return self;
}
ast_propagate_effects(self, entity);
ast_propagate_effects(self, field);
- if (!ast_type_adopt(self, outtype)) {
- ast_entfield_delete(self);
- return NULL;
- }
-
+ ast_type_adopt(self, outtype);
return self;
}
ast_propagate_effects(self, array);
ast_propagate_effects(self, index);
- if (!ast_type_adopt(self, outtype)) {
- ast_array_index_delete(self);
- return NULL;
- }
+ ast_type_adopt(self, outtype);
if (array->expression.vtype == TYPE_FIELD && outtype->expression.vtype == TYPE_ARRAY) {
if (self->expression.vtype != TYPE_ARRAY) {
compile_error(ast_ctx(self), "array_index node on type");
void ast_array_index_delete(ast_array_index *self)
{
- ast_unref(self->array);
- ast_unref(self->index);
+ if (self->array)
+ ast_unref(self->array);
+ if (self->index)
+ ast_unref(self->index);
ast_expression_delete((ast_expression*)self);
mem_d(self);
}
if (ontrue->expression.vtype == TYPE_NIL)
exprtype = onfalse;
- if (!ast_type_adopt(self, exprtype)) {
- ast_ternary_delete(self);
- return NULL;
- }
+ ast_type_adopt(self, exprtype);
return self;
}
self->dest = dest;
self->source = source;
- if (!ast_type_adopt(self, dest)) {
- ast_delete(self);
- return NULL;
- }
+ ast_type_adopt(self, dest);
return self;
}
ast_delete(self->expression.next);
self->expression.next = NULL;
}
- if (!ast_type_adopt(self, e)) {
- compile_error(ast_ctx(self), "internal error: failed to adopt type");
- return false;
- }
+ ast_type_adopt(self, e);
return true;
}
mem_d(self);
}
-bool ast_block_set_type(ast_block *self, ast_expression *from)
+void ast_block_set_type(ast_block *self, ast_expression *from)
{
if (self->expression.next)
ast_delete(self->expression.next);
- if (!ast_type_adopt(self, from))
- return false;
- return true;
+ ast_type_adopt(self, from);
}
ast_function* ast_function_new(lex_ctx ctx, const char *name, ast_value *vtype)
size_t len;
char *from;
- if (!opts.dump && !opts.dumpfin && !opts.debug)
+ if (!OPTS_OPTION_BOOL(OPTION_DUMP) &&
+ !OPTS_OPTION_BOOL(OPTION_DUMPFIN) &&
+ !OPTS_OPTION_BOOL(OPTION_DEBUG))
+ {
return NULL;
+ }
id = (self->labelcount++);
len = strlen(prefix);
}
/* we are lame now - considering the way QC works we won't tolerate arrays > 1024 elements */
- if (!array->expression.count || array->expression.count > opts.max_array_size)
+ if (!array->expression.count || array->expression.count > OPTS_OPTION_U32(OPTION_MAX_ARRAY_SIZE))
compile_error(ast_ctx(self), "Invalid array of size %lu", (unsigned long)array->expression.count);
elemtype = &array->expression.next->expression;
int vtype = elemtype->vtype;
/* same as with field arrays */
- if (!self->expression.count || self->expression.count > opts.max_array_size)
+ if (!self->expression.count || self->expression.count > OPTS_OPTION_U32(OPTION_MAX_ARRAY_SIZE))
compile_error(ast_ctx(self), "Invalid array of size %lu", (unsigned long)self->expression.count);
v = ir_builder_create_global(ir, self->name, vtype);
}
/* we are lame now - considering the way QC works we won't tolerate arrays > 1024 elements */
- if (!self->expression.count || self->expression.count > opts.max_array_size) {
+ if (!self->expression.count || self->expression.count > OPTS_OPTION_U32(OPTION_MAX_ARRAY_SIZE)) {
compile_error(ast_ctx(self), "Invalid array of size %lu", (unsigned long)self->expression.count);
}
for (i = 0; i < vec_size(self->locals); ++i)
{
if (!ast_local_codegen(self->locals[i], func->ir_func, false)) {
- if (opts.debug)
+ if (OPTS_OPTION_BOOL(OPTION_DEBUG))
compile_error(ast_ctx(self), "failed to generate local `%s`", self->locals[i]->name);
return false;
}
if (!lvalue && self->expression.outr) {
*out = self->expression.outr;
+ return true;
}
if (lvalue && self->expression.outl) {
*out = self->expression.outl;
+ return true;
}
if (!ast_istype(self->array, ast_value)) {
return true;
cmpinstr = type_eq_instr[irop->vtype];
- if (cmpinstr >= AINSTR_END) {
+ if (cmpinstr >= VINSTR_END) {
ast_type_to_string(self->operand, typestr, sizeof(typestr));
compile_error(ast_ctx(self), "invalid type to perform a switch on: %s", typestr);
return false;