self->expression.next = NULL;
self->expression.outl = NULL;
self->expression.outr = NULL;
- self->expression.variadic = false;
self->expression.params = NULL;
self->expression.count = 0;
+ self->expression.flags = 0;
}
static void ast_expression_delete(ast_expression *self)
}
fromex = &self->expression;
selfex = &cp->expression;
- selfex->variadic = fromex->variadic;
+ selfex->count = fromex->count;
+ selfex->flags = fromex->flags;
for (i = 0; i < vec_size(fromex->params); ++i) {
ast_value *v = ast_value_copy(fromex->params[i]);
if (!v) {
}
fromex = &other->expression;
selfex = &self->expression;
- selfex->variadic = fromex->variadic;
+ selfex->count = fromex->count;
+ selfex->flags = fromex->flags;
for (i = 0; i < vec_size(fromex->params); ++i) {
ast_value *v = ast_value_copy(fromex->params[i]);
if (!v)
else
selfex->next = NULL;
- selfex->variadic = fromex->variadic;
+ selfex->count = fromex->count;
+ 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;
if (vec_size(a->expression.params) != vec_size(b->expression.params))
return false;
- if (a->expression.variadic != b->expression.variadic)
+ if (a->expression.flags != b->expression.flags)
return false;
if (vec_size(a->expression.params)) {
size_t i;
if (op >= INSTR_EQ_F && op <= INSTR_GT)
self->expression.vtype = TYPE_FLOAT;
- else if (op == INSTR_AND || op == INSTR_OR ||
- op == INSTR_BITAND || op == INSTR_BITOR)
+ else if (op == INSTR_AND || op == INSTR_OR) {
+ if (OPTS_FLAG(PERL_LOGIC))
+ ast_type_adopt(self, right);
+ else
+ self->expression.vtype = TYPE_FLOAT;
+ }
+ else if (op == INSTR_BITAND || op == INSTR_BITOR)
self->expression.vtype = TYPE_FLOAT;
else if (op == INSTR_MUL_VF || op == INSTR_MUL_FV)
self->expression.vtype = TYPE_VECTOR;
size_t len;
char *from;
- if (!opts.dump && !opts.dumpfin)
+ if (!opts.dump && !opts.dumpfin && !opts.debug)
return NULL;
id = (self->labelcount++);
}
}
- options_set(opts.warn, WARN_USED_UNINITIALIZED, false);
+ opts_set(opts.warn, WARN_USED_UNINITIALIZED, false);
if (self->setter) {
if (!ast_global_codegen (self->setter, ir, false) ||
!ast_function_codegen(self->setter->constval.vfunc, ir) ||
!ir_function_finalize(self->setter->constval.vfunc->ir_func))
{
compile_error(ast_ctx(self), "internal error: failed to generate setter for `%s`", self->name);
- options_set(opts.warn, WARN_USED_UNINITIALIZED, warn);
+ opts_set(opts.warn, WARN_USED_UNINITIALIZED, warn);
return false;
}
}
!ir_function_finalize(self->getter->constval.vfunc->ir_func))
{
compile_error(ast_ctx(self), "internal error: failed to generate getter for `%s`", self->name);
- options_set(opts.warn, WARN_USED_UNINITIALIZED, warn);
+ opts_set(opts.warn, WARN_USED_UNINITIALIZED, warn);
return false;
}
}
for (i = 0; i < self->expression.count; ++i) {
vec_free(self->ir_values[i]->life);
}
- options_set(opts.warn, WARN_USED_UNINITIALIZED, warn);
+ opts_set(opts.warn, WARN_USED_UNINITIALIZED, warn);
return true;
}
for (i = 0; i < vec_size(self->exprs); ++i)
{
- ast_expression_codegen *gen = self->exprs[i]->expression.codegen;
+ ast_expression_codegen *gen;
if (func->curblock->final && !ast_istype(self->exprs[i], ast_label)) {
- compile_error(ast_ctx(self->exprs[i]), "unreachable statement");
- return false;
+ if (compile_warning(ast_ctx(self->exprs[i]), WARN_UNREACHABLE_CODE, "unreachable statement"))
+ return false;
+ continue;
}
+ gen = self->exprs[i]->expression.codegen;
if (!(*gen)(self->exprs[i], func, false, out))
return false;
}
if (!(*cgen)((ast_expression*)(self->source), func, false, &right))
return false;
- call = ir_block_create_call(func->curblock, ast_ctx(self), ast_function_label(func, "store"), funval);
+ call = ir_block_create_call(func->curblock, ast_ctx(self), ast_function_label(func, "store"), funval, false);
if (!call)
return false;
ir_call_param(call, iridx);
if (!(*cgen)((ast_expression*)(arr->setter), func, true, &funval))
return false;
- call = ir_block_create_call(func->curblock, ast_ctx(self), ast_function_label(func, "store"), funval);
+ call = ir_block_create_call(func->curblock, ast_ctx(self), ast_function_label(func, "store"), funval, false);
if (!call)
return false;
ir_call_param(call, iridx);
if (!(*cgen)((ast_expression*)(arr->getter), func, true, &funval))
return false;
- call = ir_block_create_call(func->curblock, ast_ctx(self), ast_function_label(func, "fetch"), funval);
+ call = ir_block_create_call(func->curblock, ast_ctx(self), ast_function_label(func, "fetch"), funval, false);
if (!call)
return false;
ir_call_param(call, iridx);
ir_value *condval;
ir_value *dummy;
- ir_block *cond = func->curblock;
+ ir_block *cond;
ir_block *ontrue;
ir_block *onfalse;
ir_block *ontrue_endblock = NULL;
{
ast_expression_codegen *cgen;
- ast_switch_case *def_case = NULL;
- ir_block *def_bfall = NULL;
+ ast_switch_case *def_case = NULL;
+ ir_block *def_bfall = NULL;
+ ir_block *def_bfall_to = NULL;
+ bool set_def_bfall_to = false;
ir_value *dummy = NULL;
ir_value *irop = NULL;
bnot = ir_function_create_block(ast_ctx(self), func->ir_func, ast_function_label(func, "not_case"));
if (!bcase || !bnot)
return false;
+ if (set_def_bfall_to) {
+ set_def_bfall_to = false;
+ def_bfall_to = bcase;
+ }
if (!ir_block_create_if(func->curblock, ast_ctx(self), cond, bcase, bnot))
return false;
bfall = NULL;
/* remember which case it was */
def_case = swcase;
+ /* And the next case will be remembered */
+ set_def_bfall_to = true;
}
}
cgen = def_case->code->expression.codegen;
if (!(*cgen)((ast_expression*)def_case->code, func, false, &dummy))
return false;
+
+ /* see if we need to fall through */
+ if (def_bfall_to && !func->curblock->final)
+ {
+ if (!ir_block_create_jump(func->curblock, ast_ctx(self), def_bfall_to))
+ return false;
+ }
}
/* Jump from the last bnot to bout */
vec_push(params, param);
}
- callinstr = ir_block_create_call(func->curblock, ast_ctx(self), ast_function_label(func, "call"), funval);
+ callinstr = ir_block_create_call(func->curblock, ast_ctx(self),
+ ast_function_label(func, "call"),
+ funval, !!(self->func->expression.flags & AST_FLAG_NORETURN));
if (!callinstr)
goto error;