]> git.sur5r.net Git - cc65/blobdiff - src/cc65/stmt.c
Fixed a bug
[cc65] / src / cc65 / stmt.c
index 3863c72e5f3bf4a213aeb31851885e2e20b2050d..77b39859d1775972f743138e40e48946c9c9f4b1 100644 (file)
@@ -6,7 +6,7 @@
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
-/* (C) 1998-2001 Ullrich von Bassewitz                                       */
+/* (C) 1998-2003 Ullrich von Bassewitz                                       */
 /*               Wacholderweg 14                                             */
 /*               D-70597 Stuttgart                                           */
 /* EMail:        uz@cc65.org                                                 */
 #include "swstmt.h"
 #include "symtab.h"
 #include "stmt.h"
-
-
-
-/*****************************************************************************/
-/*                                  Data                                    */
-/*****************************************************************************/
-
-
-
-/* Maximum count of cases */
-#define CASE_MAX       257
+#include "typeconv.h"
 
 
 
@@ -85,22 +75,40 @@ static void CheckTok (token_t Tok, const char* Msg, int* PendingToken)
  */
 {
     if (CurTok.Tok != Tok) {
-       Error (Msg);
+       Error (Msg);
     } else if (PendingToken) {
-       *PendingToken = 1;
+       *PendingToken = 1;
     } else {
-       NextToken ();
+       NextToken ();
     }
 }
 
 
 
 static void CheckSemi (int* PendingToken)
-/* Helper function for Statement. Will call CheckTok with the parameters
- * for a semicolon.
+/* Helper function for Statement. Will check for a semicolon and print an
+ * error message if not found (plus some error recovery). If PendingToken is
+ * NULL, it will the skip the token, otherwise it will store one to
+ * PendingToken.
+ * This function is a special version of CheckTok with the addition of the
+ * error recovery.
  */
 {
-    CheckTok (TOK_SEMI, "`;' expected", PendingToken);
+    int HaveToken = (CurTok.Tok == TOK_SEMI);
+    if (!HaveToken) {
+       Error ("`;' expected");
+        /* Try to be smart about errors */
+        if (CurTok.Tok == TOK_COLON || CurTok.Tok == TOK_COMMA) {
+            HaveToken = 1;
+        }
+    }
+    if (HaveToken) {
+        if (PendingToken) {
+            *PendingToken = 1;
+        } else {
+            NextToken ();
+        }
+    }
 }
 
 
@@ -132,7 +140,7 @@ static int IfStatement (void)
 
     /* Generate a jump label and parse the condition */
     Label1 = GetLocalLabel ();
-    test (Label1, 0);
+    TestInParens (Label1, 0);
 
     /* Parse the if body */
     GotBreak = Statement (0);
@@ -193,7 +201,7 @@ static void DoStatement (void)
 
     /* Parse the end condition */
     Consume (TOK_WHILE, "`while' expected");
-    test (loop, 1);
+    TestInParens (loop, 1);
     ConsumeSemi ();
 
     /* Define the break label */
@@ -224,7 +232,7 @@ static void WhileStatement (void)
     g_defcodelabel (loop);
 
     /* Test the loop condition */
-    test (lab, 0);
+    TestInParens (lab, 0);
 
     /* Loop body */
     Statement (&PendingToken);
@@ -235,8 +243,8 @@ static void WhileStatement (void)
     /* Exit label */
     g_defcodelabel (lab);
 
-    /* Eat remaining tokens that were delayed because of line info 
-     * correctness 
+    /* Eat remaining tokens that were delayed because of line info
+     * correctness
      */
     SkipPending (PendingToken);
 
@@ -249,30 +257,39 @@ static void WhileStatement (void)
 static void ReturnStatement (void)
 /* Handle the 'return' statement */
 {
-    ExprDesc lval;
+    ExprDesc Expr;
+    int k;
 
     NextToken ();
     if (CurTok.Tok != TOK_SEMI) {
-               if (HasVoidReturn (CurrentFunc)) {
+
+        /* Check if the function has a return value declared */
+               if (F_HasVoidReturn (CurrentFunc)) {
                    Error ("Returning a value in function with return type void");
                }
 
-       /* Evaluate the return expression. Result will be in primary */
-       expression (&lval);
+       /* Evaluate the return expression */
+       k = hie0 (InitExprDesc (&Expr));
 
-       /* Convert the return value to the type of the function result */
-       if (!HasVoidReturn (CurrentFunc)) {
-                   assignadjust (GetReturnType (CurrentFunc), &lval);
+       /* Ignore the return expression if the function returns void */
+       if (!F_HasVoidReturn (CurrentFunc)) {
+
+           /* Convert the return value to the type of the function result */
+           k = TypeConversion (&Expr, k, F_GetReturnType (CurrentFunc));
+
+           /* Load the value into the primary */
+           ExprLoad (CF_NONE, k, &Expr);
        }
-    } else if (!HasVoidReturn (CurrentFunc)) {
-       Error ("Function `%s' must return a value", GetFuncName (CurrentFunc));
+
+    } else if (!F_HasVoidReturn (CurrentFunc) && !F_HasOldStyleIntRet (CurrentFunc)) {
+       Error ("Function `%s' must return a value", F_GetFuncName (CurrentFunc));
     }
 
     /* Cleanup the stack in case we're inside a block with locals */
-    g_space (oursp - GetTopLevelSP (CurrentFunc));
+    g_space (oursp - F_GetTopLevelSP (CurrentFunc));
 
     /* Output a jump to the function exit code */
-    g_jump (GetRetLab (CurrentFunc));
+    g_jump (F_GetRetLab (CurrentFunc));
 }
 
 
@@ -347,7 +364,6 @@ static void ForStatement (void)
 /* Handle a 'for' statement */
 {
     ExprDesc lval1;
-    ExprDesc lval2;
     ExprDesc lval3;
     int HaveIncExpr;
     CodeMark IncExprStart;
@@ -380,8 +396,7 @@ static void ForStatement (void)
 
     /* Parse the test expression */
     if (CurTok.Tok != TOK_SEMI) {
-       boolexpr (&lval2);
-       g_truejump (CF_NONE, lstat);
+        Test (lstat, 1);
        g_jump (lab);
     } else {
        g_jump (lstat);
@@ -554,7 +569,7 @@ int Statement (int* PendingToken)
 
            case TOK_SEMI:
                /* Ignore it */
-               NextToken ();
+               CheckSemi (PendingToken);
                break;
 
            case TOK_PRAGMA:
@@ -572,4 +587,4 @@ int Statement (int* PendingToken)
 
 
 
-     
+