if (v->constval.vstring && OPTS_FLAG(TRUE_EMPTY_STRINGS))
return true;
return !!v->constval.vstring[0];
- case TYPE_ENTITY:
- return !!v->constval.ventity;
- case TYPE_FIELD:
- return !!v->constval.vfield;
default:
compile_error(ctx, "internal error: immediate_is_true on invalid type");
return !!v->constval.vfunc;
util_htset(vec_last(parser->variables), name, (void*)e);
}
+static ast_expression* process_condition(parser_t *parser, ast_expression *cond, bool *_ifnot)
+{
+ 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)) {
+ /* everything must use a NOT_ */
+ unary = (ast_unary*)cond;
+ 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) */
+ {
+ cond = unary->operand;
+ unary->operand = NULL;
+ ast_delete(unary);
+ ifnot = !ifnot;
+ unary = (ast_unary*)cond;
+ }
+
+ if (!cond)
+ parseerror(parser, "internal error: failed to process condition");
+
+ if (ifnot) *_ifnot = !*_ifnot;
+ return cond;
+}
+
static bool parse_if(parser_t *parser, ast_block *block, ast_expression **out)
{
ast_ifthen *ifthen;
- ast_expression *cond, *ontrue, *onfalse = NULL;
+ ast_expression *cond, *ontrue = NULL, *onfalse = NULL;
bool ifnot = false;
lex_ctx ctx = parser_ctx(parser);
}
}
+ cond = process_condition(parser, cond, &ifnot);
+ if (!cond) {
+ if (ontrue) ast_delete(ontrue);
+ if (onfalse) ast_delete(onfalse);
+ return false;
+ }
+
if (ifnot)
ifthen = ast_ifthen_new(ctx, cond, onfalse, ontrue);
else
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);
+ if (cond) {
+ 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))