]> git.sur5r.net Git - cc65/blobdiff - src/cc65/stmt.c
Working on the new backend
[cc65] / src / cc65 / stmt.c
index 833d49c70c644cad41f0db0751b6b1f5607fa1cd..64ab2aa2beea06fd9c0d754954bb35f96b49adf2 100644 (file)
 
 
 
-static int statement (void);
-/* Forward decl */
-
-
-
 static int doif (void)
 /* Handle 'if' statement here */
 {
@@ -67,11 +62,11 @@ static int doif (void)
     NextToken ();
 
     /* Generate a jump label and parse the condition */
-    flab1 = GetLabel ();
+    flab1 = GetLocalLabel ();
     test (flab1, 0);
 
     /* Parse the if body */
-    gotbreak = statement ();
+    gotbreak = Statement ();
 
     /* Else clause present? */
     if (curtok != TOK_ELSE) {
@@ -92,14 +87,14 @@ static int doif (void)
         * clause, since the jump is never reached.
         */
        if (!gotbreak) {
-           flab2 = GetLabel ();
+           flab2 = GetLocalLabel ();
            g_jump (flab2);
        } else {
            /* Mark the label as unused */
            flab2 = 0;
        }
        g_defloclabel (flab1);
-       gotbreak &= statement ();
+       gotbreak &= Statement ();
 
        /* Generate the label for the else clause */
        if (flab2) {
@@ -120,8 +115,8 @@ static void dowhile (char wtype)
     int lab;
 
     NextToken ();
-    loop = GetLabel ();
-    lab = GetLabel ();
+    loop = GetLocalLabel ();
+    lab = GetLocalLabel ();
     AddLoop (oursp, loop, lab, 0, 0);
     g_defloclabel (loop);
     if (wtype == 'w') {
@@ -142,7 +137,7 @@ static void dowhile (char wtype)
            g_truejump (CF_NONE, loop);
        } else {
            /* There is code inside the while loop */
-           statement ();
+           Statement ();
            g_jump (loop);
            g_defloclabel (lab);
        }
@@ -150,7 +145,7 @@ static void dowhile (char wtype)
     } else {
 
        /* Do loop */
-               statement ();
+               Statement ();
        Consume (TOK_WHILE, "`while' expected");
        test (loop, 1);
        ConsumeSemi ();
@@ -162,36 +157,33 @@ static void dowhile (char wtype)
 
 
 
-static void doreturn (void)
+static void DoReturn (void)
 /* Handle 'return' statement here */
 {
     struct expent lval;
-    unsigned Flags = 0;                /* Code generator flags */
-    int HaveVal = 0;           /* Do we have a return value in ax? */
-
 
     NextToken ();
     if (curtok != TOK_SEMI) {
                if (HasVoidReturn (CurrentFunc)) {
                    Error ("Returning a value in function with return type void");
                }
-               if (evalexpr (CF_NONE, hie0, &lval) == 0) {
-                   /* Constant value */
-                   Flags = CF_CONST;
-               } else {
-           /* Value in the primary register */
-           HaveVal = 1;
-       }
+
+       /* Evaluate the return expression. Result will be in primary */
+       expression (&lval);
 
        /* Convert the return value to the type of the function result */
        if (!HasVoidReturn (CurrentFunc)) {
-                   Flags |= (assignadjust (GetReturnType (CurrentFunc), &lval) & ~CF_CONST) | CF_REG;
+                   assignadjust (GetReturnType (CurrentFunc), &lval);
        }
     } else if (!HasVoidReturn (CurrentFunc)) {
        Error ("Function `%s' must return a value", GetFuncName (CurrentFunc));
     }
-    RestoreRegVars (HaveVal);
-    g_leave (Flags, lval.e_const);
+
+    /* Cleanup the stack in case we're inside a block with locals */
+    g_space (oursp - GetTopLevelSP (CurrentFunc));
+
+    /* Output a jump to the function exit code */
+    g_jump (GetRetLab (CurrentFunc));
 }
 
 
@@ -277,7 +269,7 @@ static void cascadeswitch (struct expent* eval)
 
 
     /* Create a loop so we may break out, init labels */
-    ExitLab = GetLabel ();
+    ExitLab = GetLocalLabel ();
     AddLoop (oursp, 0, ExitLab, 0, 0);
 
     /* Setup some variables needed in the loop  below */
@@ -298,7 +290,7 @@ static void cascadeswitch (struct expent* eval)
            if (!HaveBreak) {
                /* Define a label for the code */
                if (CodeLab == 0) {
-                   CodeLab = GetLabel ();
+                   CodeLab = GetLocalLabel ();
                }
                g_jump (CodeLab);
            }
@@ -371,13 +363,13 @@ static void cascadeswitch (struct expent* eval)
                    if (curtok == TOK_CASE) {
                        /* Create a code label if needed */
                        if (CodeLab == 0) {
-                           CodeLab = GetLabel ();
+                           CodeLab = GetLocalLabel ();
                        }
                        g_falsejump (CF_NONE, CodeLab);
                    } else if (curtok != TOK_DEFAULT) {
                        /* No case follows, jump to next selector */
                        if (NextLab == 0) {
-                           NextLab = GetLabel ();
+                           NextLab = GetLocalLabel ();
                        }
                        g_truejump (CF_NONE, NextLab);
                    }
@@ -393,7 +385,7 @@ static void cascadeswitch (struct expent* eval)
                    /* Handle the pathologic case: DEFAULT followed by CASE */
                    if (curtok == TOK_CASE) {
                        if (CodeLab == 0) {
-                           CodeLab = GetLabel ();
+                           CodeLab = GetLocalLabel ();
                        }
                        g_jump (CodeLab);
                    }
@@ -414,7 +406,7 @@ static void cascadeswitch (struct expent* eval)
 
        /* Parse statements */
        if (curtok != TOK_RCURLY) {
-                   HaveBreak = statement ();
+                   HaveBreak = Statement ();
        }
     }
 
@@ -468,19 +460,19 @@ static void tableswitch (struct expent* eval)
     HaveBreak = 0;             /* Keep gcc silent */
     HaveDefault = 0;           /* No default case until now */
     dlabel = 0;                        /* init */
-    lab = GetLabel ();         /* get exit */
+    lab = GetLocalLabel ();    /* get exit */
     p = swtab;
     AddLoop (oursp, 0, lab, 0, 0);
 
     /* Jump behind the code for the CASE labels */
-    g_jump (lcase = GetLabel ());
+    g_jump (lcase = GetLocalLabel ());
     lcount = 0;
     while (curtok != TOK_RCURLY) {
        if (curtok == TOK_CASE || curtok == TOK_DEFAULT) {
            if (lcount >= CASE_MAX) {
                        Fatal ("Too many case labels");
            }
-           label = GetLabel ();
+           label = GetLocalLabel ();
            do {
                if (curtok == TOK_CASE) {
                            NextToken ();
@@ -503,7 +495,7 @@ static void tableswitch (struct expent* eval)
            HaveBreak = 0;
        }
        if (curtok != TOK_RCURLY) {
-           HaveBreak = statement ();
+           HaveBreak = Statement ();
        }
     }
 
@@ -589,10 +581,10 @@ static void dofor (void)
     struct expent lval3;
 
     NextToken ();
-    loop = GetLabel ();
-    lab = GetLabel ();
-    linc = GetLabel ();
-    lstat = GetLabel ();
+    loop = GetLocalLabel ();
+    lab = GetLocalLabel ();
+    linc = GetLocalLabel ();
+    lstat = GetLocalLabel ();
     AddLoop (oursp, loop, lab, linc, lstat);
     ConsumeLParen ();
     if (curtok != TOK_SEMI) {  /* exp1 */
@@ -615,7 +607,7 @@ static void dofor (void)
     ConsumeRParen ();
     g_jump (loop);
     g_defloclabel (lstat);
-    statement ();
+    Statement ();
     g_jump (linc);
     g_defloclabel (lab);
     DelLoop ();
@@ -623,9 +615,58 @@ static void dofor (void)
 
 
 
-static int statement (void)
-/* Statement parser. Called whenever syntax requires a statement.
- * This routine performs that statement and returns 1 if it is a branch,
+static int CompoundStatement (void)
+/* Compound statement. Allow any number of statements inside braces. */
+{
+    int isbrk;
+    int oldsp;
+
+    /* eat LCURLY */
+    NextToken ();
+
+    /* Remember the stack at block entry */
+    oldsp = oursp;
+
+    /* Enter a new lexical level */
+    EnterBlockLevel ();
+
+    /* Parse local variable declarations if any */
+    DeclareLocals ();
+
+    /* Now process statements in this block */
+    isbrk = 0;
+    while (curtok != TOK_RCURLY) {
+       if (curtok != TOK_CEOF) {
+           isbrk = Statement ();
+       } else {
+           break;
+       }
+    }
+
+    /* Emit references to imports/exports for this block */
+    EmitExternals ();
+
+    /* Clean up the stack. */
+    if (isbrk) {
+       oursp = oldsp;
+    } else {
+       g_space (oursp - oldsp);
+       oursp = oldsp;
+    }
+
+    /* Leave the lexical level */
+    LeaveBlockLevel ();
+
+    /* Eat closing brace */
+    ConsumeRCurly ();
+
+    return isbrk;
+}
+
+
+
+int Statement (void)
+/* Statement parser. Returns 1 if the statement does a return/break, returns
  * 0 otherwise
  */
 {
@@ -642,10 +683,10 @@ static int statement (void)
        switch (curtok) {
 
            case TOK_LCURLY:
-               return compound ();
+               return CompoundStatement ();
 
            case TOK_IF:
-               return doif ();
+               return doif ();
 
            case TOK_WHILE:
                dowhile ('w');
@@ -660,7 +701,7 @@ static int statement (void)
                break;
 
            case TOK_RETURN:
-               doreturn ();
+               DoReturn ();
                ConsumeSemi ();
                return 1;
 
@@ -704,61 +745,3 @@ static int statement (void)
 
 
 
-int compound (void)
-/* Compound statement.         Allow any number of statements, inside braces. */
-{
-    static unsigned CurrentLevel = 0;
-
-    int isbrk;
-    int oldsp;
-
-    /* eat LCURLY */
-    NextToken ();
-
-    /* Remember the stack at block entry */
-    oldsp = oursp;
-
-    /* If we're not on function level, enter a new lexical level */
-    if (CurrentLevel++ > 0) {
-       /* A nested block */
-       EnterBlockLevel ();
-    }
-
-    /* Parse local variable declarations if any */
-    DeclareLocals ();
-
-    /* Now process statements in the function body */
-    isbrk = 0;
-    while (curtok != TOK_RCURLY) {
-       if (curtok == TOK_CEOF)
-           break;
-       else {
-           isbrk = statement ();
-       }
-    }
-
-    /* Emit references to imports/exports for this block */
-    EmitExternals ();
-
-    /* If this is not the top level compound statement, clean up the stack.
-     * For a top level statement this will be done by the function exit code.
-     */
-    if (--CurrentLevel != 0) {
-       /* Some sort of nested block */
-       LeaveBlockLevel ();
-       if (isbrk) {
-           oursp = oldsp;
-       } else {
-           g_space (oursp - oldsp);
-           oursp = oldsp;
-       }
-    }
-
-    /* Eat closing brace */
-    ConsumeRCurly ();
-
-    return isbrk;
-}
-
-
-