X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=src%2Fcc65%2Fstmt.c;h=77b39859d1775972f743138e40e48946c9c9f4b1;hb=b3496bb343a2c93284a8669da4b52cf45b3db3dd;hp=3863c72e5f3bf4a213aeb31851885e2e20b2050d;hpb=88dfee564224395aab76b1676a91f844a901c4d1;p=cc65 diff --git a/src/cc65/stmt.c b/src/cc65/stmt.c index 3863c72e5..77b39859d 100644 --- a/src/cc65/stmt.c +++ b/src/cc65/stmt.c @@ -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 */ @@ -58,17 +58,7 @@ #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) - +