int hie0 (ExprDesc *lval);
/* Parse comma operator. */
-static int expr (int (*func) (ExprDesc*), ExprDesc *lval);
+int expr (int (*func) (ExprDesc*), ExprDesc *lval);
/* Expression parser; func is either hie0 or hie1. */
-static int expr (int (*func) (ExprDesc*), ExprDesc *lval)
+int expr (int (*func) (ExprDesc*), ExprDesc *lval)
/* Expression parser; func is either hie0 or hie1. */
{
int k;
-void Test (unsigned Label, int Invert)
-/* Evaluate a boolean test expression and jump depending on the result of
- * the test and on Invert.
- */
-{
- int k;
- ExprDesc lval;
-
- /* Evaluate the expression */
- k = expr (hie0, InitExprDesc (&lval));
-
- /* Check for a boolean expression */
- CheckBoolExpr (&lval);
-
- /* Check for a constant expression */
- if (k == 0 && lval.Flags == E_MCONST) {
-
- /* Constant rvalue */
- if (!Invert && lval.ConstVal == 0) {
- g_jump (Label);
- Warning ("Unreachable code");
- } else if (Invert && lval.ConstVal != 0) {
- g_jump (Label);
- }
-
- } else {
-
- /* If the expr hasn't set condition codes, set the force-test flag */
- if ((lval.Test & E_CC) == 0) {
- lval.Test |= E_FORCETEST;
- }
-
- /* Load the value into the primary register */
- ExprLoad (CF_FORCECHAR, k, &lval);
-
- /* Generate the jump */
- if (Invert) {
- g_truejump (CF_NONE, Label);
- } else {
- g_falsejump (CF_NONE, Label);
- }
- }
-}
-
-
-
-void TestInParens (unsigned Label, int Invert)
-/* Evaluate a boolean test expression in parenthesis and jump depending on
- * the result of the test * and on Invert.
- */
-{
- /* Eat the parenthesis */
- ConsumeLParen ();
-
- /* Do the test */
- Test (Label, Invert);
-
- /* Check for the closing brace */
- ConsumeRParen ();
-}
-
-
-
* primary register and 1 is returned.
*/
+int expr (int (*func) (ExprDesc*), ExprDesc *lval);
+/* Expression parser; func is either hie0 or hie1. */
+
void expression1 (ExprDesc* lval);
/* Evaluate an expression on level 1 (no comma operator) and put it into
* the primary register
void DefineData (ExprDesc* lval);
/* Output a data definition for the given expression */
-void Test (unsigned Label, int Invert);
-/* Evaluate a boolean test expression and jump depending on the result of
- * the test and on Invert.
- */
-
-void TestInParens (unsigned Label, int Invert);
-/* Evaluate a boolean test expression in parenthesis and jump depending on
- * the result of the test * and on Invert.
- */
-
/* End of expr.h */
swstmt.o \
symentry.o \
symtab.o \
+ testexpr.o \
textseg.o \
typecmp.o \
typeconv.o \
swstmt.obj \
symentry.obj \
symtab.obj \
+ testexpr.obj \
textseg.obj \
typecmp.obj \
typeconv.obj \
#include "swstmt.h"
#include "symtab.h"
#include "stmt.h"
+#include "testexpr.h"
#include "typeconv.h"
/* Handle an 'if' statement */
{
unsigned Label1;
+ unsigned TestResult;
int GotBreak;
/* Skip the if */
/* Generate a jump label and parse the condition */
Label1 = GetLocalLabel ();
- TestInParens (Label1, 0);
+ TestResult = TestInParens (Label1, 0);
/* Parse the if body */
GotBreak = Statement (0);
} else {
- /* Generate a jump around the else branch */
+ /* Generate a jump around the else branch */
unsigned Label2 = GetLocalLabel ();
- g_jump (Label2);
+ g_jump (Label2);
- /* Skip the else */
+ /* Skip the else */
NextToken ();
- /* Define the target for the first test */
- g_defcodelabel (Label1);
+ /* If the if expression was always true, the code in the else branch
+ * is never executed. Output a warning if this is the case.
+ */
+ if (TestResult == TESTEXPR_TRUE) {
+ Warning ("Unreachable code");
+ }
+
+ /* Define the target for the first test */
+ g_defcodelabel (Label1);
- /* Total break only if both branches had a break. */
+ /* Total break only if both branches had a break. */
GotBreak &= Statement (0);
/* Generate the label for the else clause */
- g_defcodelabel (Label2);
+ g_defcodelabel (Label2);
/* Done */
return GotBreak;
--- /dev/null
+/*****************************************************************************/
+/* */
+/* 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. */
+/* */
+/*****************************************************************************/
+
+
+
+#include "codegen.h"
+#include "error.h"
+#include "expr.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 lval;
+ unsigned Result;
+
+ /* Evaluate the expression */
+ int k = expr (hie0, InitExprDesc (&lval));
+
+ /* Check for a boolean expression */
+ CheckBoolExpr (&lval);
+
+ /* Check for a constant expression */
+ if (k == 0 && lval.Flags == E_MCONST) {
+
+ /* Result is constant, so we know the outcome */
+ Result = (lval.ConstVal != 0);
+
+ /* Constant rvalue */
+ if (!Invert && lval.ConstVal == 0) {
+ g_jump (Label);
+ Warning ("Unreachable code");
+ } else if (Invert && lval.ConstVal != 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 ((lval.Test & E_CC) == 0) {
+ lval.Test |= E_FORCETEST;
+ }
+
+ /* Load the value into the primary register */
+ ExprLoad (CF_FORCECHAR, k, &lval);
+
+ /* 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;
+}
+
+
+
+
--- /dev/null
+/*****************************************************************************/
+/* */
+/* test.h */
+/* */
+/* 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. */
+/* */
+/*****************************************************************************/
+
+
+
+#ifndef TESTEXPR_H
+#define TESTEXPR_H
+
+
+
+/*****************************************************************************/
+/* Data */
+/*****************************************************************************/
+
+
+
+#define TESTEXPR_UNKNOWN 0 /* Result of expression unknown */
+#define TESTEXPR_TRUE 1 /* Expression yields true */
+#define TESTEXPR_FALSE 2 /* Expression yields false */
+
+
+
+/*****************************************************************************/
+/* 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.
+ */
+
+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.
+ */
+
+
+
+/* End of testexpr.h */
+#endif
+
+
+
+