ast_loop* ast_loop_new(lex_ctx ctx,
ast_expression *initexpr,
- ast_expression *precond,
- ast_expression *postcond,
+ ast_expression *precond, bool pre_not,
+ ast_expression *postcond, bool post_not,
ast_expression *increment,
ast_expression *body)
{
self->increment = increment;
self->body = body;
+ self->pre_not = pre_not;
+ self->post_not = post_not;
+
if (initexpr)
ast_propagate_effects(self, initexpr);
if (precond)
else if (bpostcond) ontrue = bpostcond;
else ontrue = bprecond;
onfalse = bout;
+ if (self->pre_not) {
+ tmpblock = ontrue;
+ ontrue = onfalse;
+ onfalse = tmpblock;
+ }
if (!ir_block_create_if(end_bprecond, ast_ctx(self), precond, ontrue, onfalse))
return false;
}
else if (bincrement) ontrue = bincrement;
else ontrue = bpostcond;
onfalse = bout;
+ if (self->post_not) {
+ tmpblock = ontrue;
+ ontrue = onfalse;
+ onfalse = tmpblock;
+ }
if (!ir_block_create_if(end_bpostcond, ast_ctx(self), postcond, ontrue, onfalse))
return false;
}
ast_expression *postcond;
ast_expression *increment;
ast_expression *body;
+ /* For now we allow a seperate flag on whether or not the condition
+ * is supposed to be true or false.
+ * That way, the parser can generate a 'while not(!x)' for `while(x)`
+ * if desired, which is useful for the new -f{true,false}-empty-strings
+ * flag.
+ */
+ bool pre_not;
+ bool post_not;
};
ast_loop* ast_loop_new(lex_ctx ctx,
ast_expression *initexpr,
- ast_expression *precond,
- ast_expression *postcond,
+ ast_expression *precond, bool pre_not,
+ ast_expression *postcond, bool post_not,
ast_expression *increment,
ast_expression *body);
void ast_loop_delete(ast_loop*);
{
bool ifnot = false;
ast_unary *unary;
+ ast_expression *prev;
if (OPTS_FLAG(FALSE_EMPTY_STRINGS) && cond->expression.vtype == TYPE_STRING) {
+ prev = cond;
cond = (ast_expression*)ast_unary_new(ast_ctx(cond), INSTR_NOT_S, cond);
+ if (!cond) {
+ ast_unref(prev);
+ parseerror(parser, "internal error: failed to process condition");
+ return NULL;
+ }
ifnot = !ifnot;
}
else if (OPTS_FLAG(CORRECT_LOGIC)) {
if (!ast_istype(cond, ast_unary) || unary->op < INSTR_NOT_F || unary->op > INSTR_NOT_FNC)
{
/* use the right NOT_ */
+ prev = cond;
cond = (ast_expression*)ast_unary_new(ast_ctx(cond), type_not_instr[cond->expression.vtype], cond);
+ if (!cond) {
+ ast_unref(prev);
+ parseerror(parser, "internal error: failed to process condition");
+ return NULL;
+ }
ifnot = !ifnot;
}
}
unary = (ast_unary*)cond;
- while (ast_istype(cond, ast_unary) && unary->op == INSTR_NOT_F && unary->operand->expression.vtype != TYPE_STRING)
+ while (ast_istype(cond, ast_unary) && unary->op == INSTR_NOT_F)
+ /*&& unary->operand->expression.vtype != TYPE_STRING) */
{
cond = unary->operand;
unary->operand = NULL;
ast_loop *aloop;
ast_expression *cond, *ontrue;
+ bool ifnot = false;
+
lex_ctx ctx = parser_ctx(parser);
(void)block; /* not touching */
return false;
}
- aloop = ast_loop_new(ctx, NULL, cond, NULL, NULL, ontrue);
+ cond = process_condition(parser, cond, &ifnot);
+ if (!cond) {
+ ast_delete(ontrue);
+ return false;
+ }
+ aloop = ast_loop_new(ctx, NULL, cond, ifnot, NULL, false, NULL, ontrue);
*out = (ast_expression*)aloop;
return true;
}
ast_loop *aloop;
ast_expression *cond, *ontrue;
+ bool ifnot = false;
+
lex_ctx ctx = parser_ctx(parser);
(void)block; /* not touching */
return false;
}
- aloop = ast_loop_new(ctx, NULL, NULL, cond, NULL, ontrue);
+ cond = process_condition(parser, cond, &ifnot);
+ if (!cond) {
+ ast_delete(ontrue);
+ return false;
+ }
+ aloop = ast_loop_new(ctx, NULL, NULL, false, cond, ifnot, NULL, ontrue);
*out = (ast_expression*)aloop;
return true;
}
ast_loop *aloop;
ast_expression *initexpr, *cond, *increment, *ontrue;
ast_value *typevar;
- bool retval = true;
+
+ bool retval = true;
+ bool ifnot = false;
lex_ctx ctx = parser_ctx(parser);
if (!parse_statement_or_block(parser, &ontrue))
goto onerr;
- aloop = ast_loop_new(ctx, initexpr, cond, NULL, increment, ontrue);
+ cond = process_condition(parser, cond, &ifnot);
+ if (!cond)
+ goto onerr;
+ aloop = ast_loop_new(ctx, initexpr, cond, ifnot, NULL, false, increment, ontrue);
*out = (ast_expression*)aloop;
if (!parser_leaveblock(parser))