return self;
}
-void ast_block_add_expr(ast_block *self, ast_expression *e)
+bool ast_block_add_expr(ast_block *self, ast_expression *e)
{
ast_propagate_effects(self, e);
vec_push(self->exprs, e);
+ if (self->expression.next) {
+ 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;
+ }
+ return true;
}
void ast_block_collect(ast_block *self, ast_expression *expr)
case opid1(','):
if (blocks[0]) {
- ast_block_add_expr(blocks[0], exprs[1]);
+ if (!ast_block_add_expr(blocks[0], exprs[1]))
+ return false;
} else {
blocks[0] = ast_block_new(ctx);
- ast_block_add_expr(blocks[0], exprs[0]);
- ast_block_add_expr(blocks[0], exprs[1]);
+ if (!ast_block_add_expr(blocks[0], exprs[0]) ||
+ !ast_block_add_expr(blocks[0], exprs[1]))
+ {
+ return false;
+ }
}
if (!ast_block_set_type(blocks[0], exprs[1]))
return false;
}
if (!expr)
continue;
- ast_block_add_expr(caseblock, expr);
+ if (!ast_block_add_expr(caseblock, expr)) {
+ ast_delete(switchnode);
+ return false;
+ }
}
}
}
if (!expr)
continue;
- ast_block_add_expr(block, expr);
+ if (!ast_block_add_expr(block, expr)) {
+ ast_delete(block);
+ block = NULL;
+ goto cleanup;
+ }
}
if (parser->tok != '}') {
if (store_think) ast_delete(store_think);
retval = false;
}
- ast_block_add_expr(block, (ast_expression*)store_frame);
- ast_block_add_expr(block, (ast_expression*)store_nextthink);
- ast_block_add_expr(block, (ast_expression*)store_think);
+ if (!ast_block_add_expr(block, (ast_expression*)store_frame) ||
+ !ast_block_add_expr(block, (ast_expression*)store_nextthink) ||
+ !ast_block_add_expr(block, (ast_expression*)store_think))
+ {
+ retval = false;
+ }
}
if (!retval) {
return NULL;
}
- ast_block_add_expr(block, (ast_expression*)st);
+ if (!ast_block_add_expr(block, (ast_expression*)st)) {
+ ast_delete(block);
+ return NULL;
+ }
ret = ast_return_new(ctx, NULL);
if (!ret) {
return NULL;
}
- ast_block_add_expr(block, (ast_expression*)ret);
+ if (!ast_block_add_expr(block, (ast_expression*)ret)) {
+ ast_delete(block);
+ return NULL;
+ }
return (ast_expression*)block;
} else {
return NULL;
}
- ast_block_add_expr(block, (ast_expression*)st);
+ if (!ast_block_add_expr(block, (ast_expression*)st)) {
+ ast_delete(block);
+ return NULL;
+ }
ret = ast_return_new(ctx, NULL);
if (!ret) {
return NULL;
}
- ast_block_add_expr(block, (ast_expression*)ret);
+ if (!ast_block_add_expr(block, (ast_expression*)ret)) {
+ ast_delete(block);
+ return NULL;
+ }
return (ast_expression*)block;
} else {
goto cleanup;
}
- ast_block_add_expr(func->blocks[0], root);
array->setter = fval;
- return true;
+ return ast_block_add_expr(func->blocks[0], root);
cleanup:
if (index) ast_delete(index);
if (value) ast_delete(value);
goto cleanup;
}
- ast_block_add_expr(func->blocks[0], root);
array->setter = fval;
- return true;
+ return ast_block_add_expr(func->blocks[0], root);
cleanup:
if (entity) ast_delete(entity);
if (index) ast_delete(index);
goto cleanup;
}
- ast_block_add_expr(func->blocks[0], root);
array->getter = fval;
- return true;
+ return ast_block_add_expr(func->blocks[0], root);
cleanup:
if (index) ast_delete(index);
if (root) ast_delete(root);
else {
if (vec_size(sy.out) != 1 && vec_size(sy.ops) != 0)
parseerror(parser, "internal error: leaked operands");
- ast_block_add_expr(localblock, (ast_expression*)sy.out[0].out);
+ if (!ast_block_add_expr(localblock, (ast_expression*)sy.out[0].out))
+ break;
}
vec_free(sy.out);
vec_free(sy.ops);