]> git.sur5r.net Git - cc65/commitdiff
Move the expression test code into separate modules.
authorcuz <cuz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Tue, 2 Mar 2004 18:00:08 +0000 (18:00 +0000)
committercuz <cuz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Tue, 2 Mar 2004 18:00:08 +0000 (18:00 +0000)
The Test() and TestInParens() functions do now return information about the
expression that was tested.
An if... statement where the expression is always true will now print a
warning "Unreachable code" if it has an else clause.

git-svn-id: svn://svn.cc65.org/cc65/trunk@2889 b7a2c559-68d2-44c3-8de9-860c34a00d81

src/cc65/expr.c
src/cc65/expr.h
src/cc65/make/gcc.mak
src/cc65/make/watcom.mak
src/cc65/stmt.c
src/cc65/testexpr.c [new file with mode: 0644]
src/cc65/testexpr.h [new file with mode: 0644]

index 43df6bfa480a11f0889b759fbacde42180c550be..845b4669687a4a90071480033df94284a83dec03 100644 (file)
@@ -90,7 +90,7 @@ static GenDesc GenOASGN  = { TOK_OR_ASSIGN,   GEN_NOPUSH,     g_or  };
 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. */
 
 
@@ -2987,7 +2987,7 @@ int evalexpr (unsigned flags, int (*f) (ExprDesc*), ExprDesc* lval)
 
 
 
-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;
@@ -3071,66 +3071,3 @@ void intexpr (ExprDesc* lval)
 
 
 
-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 ();
-}
-
-
-
index 99a0af32dd45fc02aa609c00e1299506dba6e093..f60fc6d5586749e9e671a95bd8124c97dca87632 100644 (file)
@@ -61,6 +61,9 @@ int evalexpr (unsigned flags, int (*f) (ExprDesc*), ExprDesc* lval);
  * 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
@@ -87,16 +90,6 @@ int hie1 (ExprDesc* lval);
 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 */
index 179b875c5874abf1acf39b59d667f37db5f46a9b..d33a06fa155755d4c91b34a6fc1a4fc7e2b08ded 100644 (file)
@@ -84,6 +84,7 @@ OBJS =        anonname.o      \
        swstmt.o        \
        symentry.o      \
        symtab.o        \
+        testexpr.o      \
        textseg.o       \
        typecmp.o       \
         typeconv.o      \
index 101bf5c07fba8ddac0929e1532f997479fb3704e..884175a83f454624112e8dfd20f427d56dbb6404 100644 (file)
@@ -118,6 +118,7 @@ OBJS =      anonname.obj    \
        swstmt.obj      \
        symentry.obj    \
        symtab.obj      \
+        testexpr.obj    \
        textseg.obj     \
        typecmp.obj     \
         typeconv.obj    \
index 9d7b1e74ca1a1133a3026b52f0ab8d490b047d29..64ab61b79eea542248c474406ee7cee5e30dec24 100644 (file)
@@ -58,6 +58,7 @@
 #include "swstmt.h"
 #include "symtab.h"
 #include "stmt.h"
+#include "testexpr.h"
 #include "typeconv.h"
 
 
@@ -133,6 +134,7 @@ static int IfStatement (void)
 /* Handle an 'if' statement */
 {
     unsigned Label1;
+    unsigned TestResult;
     int GotBreak;
 
     /* Skip the if */
@@ -140,7 +142,7 @@ static int IfStatement (void)
 
     /* Generate a jump label and parse the condition */
     Label1 = GetLocalLabel ();
-    TestInParens (Label1, 0);
+    TestResult = TestInParens (Label1, 0);
 
     /* Parse the if body */
     GotBreak = Statement (0);
@@ -157,21 +159,28 @@ static int IfStatement (void)
 
     } 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;
diff --git a/src/cc65/testexpr.c b/src/cc65/testexpr.c
new file mode 100644 (file)
index 0000000..5defef9
--- /dev/null
@@ -0,0 +1,130 @@
+/*****************************************************************************/
+/*                                                                           */
+/*                                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;
+}
+
+
+
+
diff --git a/src/cc65/testexpr.h b/src/cc65/testexpr.h
new file mode 100644 (file)
index 0000000..2058541
--- /dev/null
@@ -0,0 +1,79 @@
+/*****************************************************************************/
+/*                                                                           */
+/*                                  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
+
+
+
+