/*****************************************************************************/ /* */ /* testexpr.c */ /* */ /* Test an expression and jump */ /* */ /* */ /* */ /* (C) 2004 Ullrich von Bassewitz */ /* Römerstraße 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ /* */ /* This software is provided 'as-is', without any expressed or implied */ /* warranty. In no event will the authors be held liable for any damages */ /* arising from the use of this software. */ /* */ /* Permission is granted to anyone to use this software for any purpose, */ /* including commercial applications, and to alter it and redistribute it */ /* freely, subject to the following restrictions: */ /* */ /* 1. The origin of this software must not be misrepresented; you must not */ /* claim that you wrote the original software. If you use this software */ /* in a product, an acknowledgment in the product documentation would be */ /* appreciated but is not required. */ /* 2. Altered source versions must be plainly marked as such, and must not */ /* be misrepresented as being the original software. */ /* 3. This notice may not be removed or altered from any source */ /* distribution. */ /* */ /*****************************************************************************/ /* cc65 */ #include "codegen.h" #include "error.h" #include "expr.h" #include "loadexpr.h" #include "scanner.h" #include "testexpr.h" /*****************************************************************************/ /* Code */ /*****************************************************************************/ unsigned Test (unsigned Label, int Invert) /* Evaluate a boolean test expression and jump depending on the result of * the test and on Invert. The function returns one of the TESTEXPR_xx codes * defined above. If the jump is always true, a warning is output. */ { ExprDesc Expr; unsigned Result; /* Read a boolean expression */ BoolExpr (hie0, &Expr); /* Check for a constant expression */ if (ED_IsConstAbs (&Expr)) { /* Result is constant, so we know the outcome */ Result = (Expr.IVal != 0); /* Constant rvalue */ if (!Invert && Expr.IVal == 0) { g_jump (Label); Warning ("Unreachable code"); } else if (Invert && Expr.IVal != 0) { g_jump (Label); } } else { /* Result is unknown */ Result = TESTEXPR_UNKNOWN; /* If the expr hasn't set condition codes, set the force-test flag */ if (!ED_IsTested (&Expr)) { ED_MarkForTest (&Expr); } /* Load the value into the primary register */ LoadExpr (CF_FORCECHAR, &Expr); /* Generate the jump */ if (Invert) { g_truejump (CF_NONE, Label); } else { g_falsejump (CF_NONE, Label); } } /* Return the result */ return Result; } unsigned TestInParens (unsigned Label, int Invert) /* Evaluate a boolean test expression in parenthesis and jump depending on * the result of the test * and on Invert. The function returns one of the * TESTEXPR_xx codes defined above. If the jump is always true, a warning is * output. */ { unsigned Result; /* Eat the parenthesis */ ConsumeLParen (); /* Do the test */ Result = Test (Label, Invert); /* Check for the closing brace */ ConsumeRParen (); /* Return the result of the expression */ return Result; }