/* */
/* */
/* */
-/* (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"
*/
{
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 ();
+ }
+ }
}
/* Generate a jump label and parse the condition */
Label1 = GetLocalLabel ();
- test (Label1, 0);
+ TestInParens (Label1, 0);
/* Parse the if body */
GotBreak = Statement (0);
/* Parse the end condition */
Consume (TOK_WHILE, "`while' expected");
- test (loop, 1);
+ TestInParens (loop, 1);
ConsumeSemi ();
/* Define the break label */
g_defcodelabel (loop);
/* Test the loop condition */
- test (lab, 0);
+ TestInParens (lab, 0);
/* Loop body */
Statement (&PendingToken);
/* 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);
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));
}
/* Handle a 'for' statement */
{
ExprDesc lval1;
- ExprDesc lval2;
ExprDesc lval3;
int HaveIncExpr;
CodeMark IncExprStart;
/* 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);
case TOK_SEMI:
/* Ignore it */
- NextToken ();
+ CheckSemi (PendingToken);
break;
case TOK_PRAGMA:
-
+