From 88dfee564224395aab76b1676a91f844a901c4d1 Mon Sep 17 00:00:00 2001 From: cuz Date: Tue, 9 Oct 2001 09:44:39 +0000 Subject: [PATCH] Module breakup git-svn-id: svn://svn.cc65.org/cc65/trunk@1017 b7a2c559-68d2-44c3-8de9-860c34a00d81 --- src/cc65/make/gcc.mak | 1 + src/cc65/make/watcom.mak | 2 + src/cc65/stmt.c | 389 +++++---------------------------------- src/cc65/stmt.h | 37 +++- src/cc65/swstmt.c | 377 +++++++++++++++++++++++++++++++++++++ src/cc65/swstmt.h | 56 ++++++ 6 files changed, 518 insertions(+), 344 deletions(-) create mode 100644 src/cc65/swstmt.c create mode 100644 src/cc65/swstmt.h diff --git a/src/cc65/make/gcc.mak b/src/cc65/make/gcc.mak index e3e28f9e8..2a34da998 100644 --- a/src/cc65/make/gcc.mak +++ b/src/cc65/make/gcc.mak @@ -70,6 +70,7 @@ OBJS = anonname.o \ segments.o \ stdfunc.o \ stmt.o \ + swstmt.o \ symentry.o \ symtab.o \ textseg.o \ diff --git a/src/cc65/make/watcom.mak b/src/cc65/make/watcom.mak index 2bb9a4326..4d7cfb370 100644 --- a/src/cc65/make/watcom.mak +++ b/src/cc65/make/watcom.mak @@ -115,6 +115,7 @@ OBJS = anonname.obj \ segments.obj \ stdfunc.obj \ stmt.obj \ + swstmt.obj \ symentry.obj \ symtab.obj \ textseg.obj \ @@ -190,6 +191,7 @@ FILE scanner.obj FILE segments.obj FILE stdfunc.obj FILE stmt.obj +FILE swstmt.obj FILE symentry.obj FILE symtab.obj FILE textseg.obj diff --git a/src/cc65/stmt.c b/src/cc65/stmt.c index 3fd066eda..3863c72e5 100644 --- a/src/cc65/stmt.c +++ b/src/cc65/stmt.c @@ -1,10 +1,35 @@ -/* - * stmt.c - * - * Ullrich von Bassewitz, 06.08.1998 - * - * Original by John R. Dunning - see copyleft.jrd - */ +/*****************************************************************************/ +/* */ +/* stmt.c */ +/* */ +/* Parse a statement */ +/* */ +/* */ +/* */ +/* (C) 1998-2001 Ullrich von Bassewitz */ +/* Wacholderweg 14 */ +/* D-70597 Stuttgart */ +/* 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. */ +/* */ +/*****************************************************************************/ @@ -30,6 +55,7 @@ #include "loop.h" #include "pragma.h" #include "scanner.h" +#include "swstmt.h" #include "symtab.h" #include "stmt.h" @@ -209,7 +235,9 @@ static void WhileStatement (void) /* Exit label */ g_defcodelabel (lab); - /* Eat remaining tokens that were delay because of line info correctness */ + /* Eat remaining tokens that were delayed because of line info + * correctness + */ SkipPending (PendingToken); /* Remove the loop from the loop stack */ @@ -262,9 +290,9 @@ static void BreakStatement (void) /* Check if we are inside a loop */ if (L == 0) { - /* Error: No current loop */ - Error ("`break' statement not within loop or switch"); - return; + /* Error: No current loop */ + Error ("`break' statement not within loop or switch"); + return; } /* Correct the stack pointer if needed */ @@ -287,19 +315,19 @@ static void ContinueStatement (void) /* Get the current loop descriptor */ L = CurrentLoop (); if (L) { - /* Search for the correct loop */ - do { - if (L->Loop) { - break; - } - L = L->Next; - } while (L); + /* Search for the correct loop */ + do { + if (L->Loop) { + break; + } + L = L->Next; + } while (L); } /* Did we find it? */ if (L == 0) { - Error ("`continue' statement not within a loop"); - return; + Error ("`continue' statement not within a loop"); + return; } /* Correct the stackpointer if needed */ @@ -315,324 +343,6 @@ static void ContinueStatement (void) -static void CascadeSwitch (ExprDesc* Expr) -/* Handle a switch statement for chars with a cmp cascade for the selector */ -{ - unsigned ExitLab; /* Exit label */ - unsigned NextLab; /* Next case label */ - unsigned CodeLab; /* Label that starts the actual selector code */ - int HaveBreak; /* Remember if we exited with break */ - int HaveDefault; /* Remember if we had a default label */ - int lcount; /* Label count */ - unsigned Flags; /* Code generator flags */ - ExprDesc lval; /* Case label expression */ - long Val; /* Case label value */ - - - /* Get the unqualified type of the switch expression */ - type ExprType = UnqualifiedType (Expr->Type[0]); - - /* Create a loop so we may break out, init labels */ - ExitLab = GetLocalLabel (); - AddLoop (oursp, 0, ExitLab, 0, 0); - - /* Setup some variables needed in the loop below */ - Flags = TypeOf (Expr->Type) | CF_CONST | CF_FORCECHAR; - CodeLab = NextLab = 0; - HaveBreak = 1; - HaveDefault = 0; - - /* Parse the labels */ - lcount = 0; - while (CurTok.Tok != TOK_RCURLY) { - - if (CurTok.Tok == TOK_CASE || CurTok.Tok == TOK_DEFAULT) { - - /* If the code for the previous selector did not end with a - * break statement, we must jump over the next selector test. - */ - if (!HaveBreak) { - /* Define a label for the code */ - if (CodeLab == 0) { - CodeLab = GetLocalLabel (); - } - g_jump (CodeLab); - } - - /* If we have a cascade label, emit it */ - if (NextLab) { - g_defcodelabel (NextLab); - NextLab = 0; - } - - while (CurTok.Tok == TOK_CASE || CurTok.Tok == TOK_DEFAULT) { - - /* Parse the selector */ - if (CurTok.Tok == TOK_CASE) { - - /* Count labels */ - ++lcount; - - /* Skip the "case" token */ - NextToken (); - - /* Read the selector expression */ - constexpr (&lval); - if (!IsClassInt (lval.Type)) { - Error ("Switch quantity not an integer"); - } - - /* Check the range of the expression */ - Val = lval.ConstVal; - switch (ExprType) { - - case T_SCHAR: - /* Signed char */ - if (Val < -128 || Val > 127) { - Error ("Range error"); - } - break; - - case T_UCHAR: - if (Val < 0 || Val > 255) { - Error ("Range error"); - } - break; - - case T_INT: - if (Val < -32768 || Val > 32767) { - Error ("Range error"); - } - break; - - case T_UINT: - if (Val < 0 || Val > 65535) { - Error ("Range error"); - } - break; - - default: - Internal ("Invalid type: %04X", ExprType); - } - - /* Emit a compare */ - g_cmp (Flags, Val); - - /* If another case follows after the colon (which is - * currently pending and cannot be skipped since otherwise - * the debug infos will get wrong), we will jump to the - * code if the condition is true. - */ - if (NextTok.Tok == TOK_CASE) { - /* Create a code label if needed */ - if (CodeLab == 0) { - CodeLab = GetLocalLabel (); - } - g_falsejump (CF_NONE, CodeLab); - } else if (NextTok.Tok != TOK_DEFAULT) { - /* No case follows, jump to next selector */ - if (NextLab == 0) { - NextLab = GetLocalLabel (); - } - g_truejump (CF_NONE, NextLab); - } - - /* Skip the colon */ - ConsumeColon (); - - } else { - - /* Default case */ - NextToken (); - - /* Handle the pathologic case: DEFAULT followed by CASE */ - if (NextTok.Tok == TOK_CASE) { - if (CodeLab == 0) { - CodeLab = GetLocalLabel (); - } - g_jump (CodeLab); - } - - /* Skip the colon */ - ConsumeColon (); - - /* Remember that we had a default label */ - HaveDefault = 1; - } - - } - - } - - /* Emit a code label if we have one */ - if (CodeLab) { - g_defcodelabel (CodeLab); - CodeLab = 0; - } - - /* Parse statements */ - if (CurTok.Tok != TOK_RCURLY) { - HaveBreak = Statement (0); - } - } - - /* Check if we have any labels */ - if (lcount == 0 && !HaveDefault) { - Warning ("No case labels"); - } - - /* Define the exit label and, if there's a next label left, create this - * one, too. - */ - if (NextLab) { - g_defcodelabel (NextLab); - } - g_defcodelabel (ExitLab); - - /* Eat the closing curly brace */ - NextToken (); - - /* End the loop */ - DelLoop (); -} - - - -static void TableSwitch (ExprDesc* Expr) -/* Handle a switch statement via table based selector */ -{ - /* Entry for one case in a switch statement */ - typedef struct { - long Value; /* selector value */ - unsigned Label; /* label for this selector */ - } SwitchEntry; - - unsigned DefaultLabel; /* Label for default case */ - unsigned ExitLabel; /* exit label */ - int lcase; /* label for compares */ - int HaveBreak; /* Last statement has a break */ - unsigned Flags; /* Code generator flags */ - ExprDesc lval; /* Case label expression */ - unsigned I; - SwitchEntry* P; - Collection SwitchTab; - - /* Initialize the collection for the switch entries */ - InitCollection (&SwitchTab); - - /* Create a look so we may break out, init labels */ - HaveBreak = 0; /* Keep gcc silent */ - DefaultLabel = 0; /* No default case until now */ - ExitLabel = GetLocalLabel (); /* get exit */ - AddLoop (oursp, 0, ExitLabel, 0, 0); - - /* Jump behind the code for the CASE labels */ - g_jump (lcase = GetLocalLabel ()); - while (CurTok.Tok != TOK_RCURLY) { - if (CurTok.Tok == TOK_CASE || CurTok.Tok == TOK_DEFAULT) { - do { - if (CurTok.Tok == TOK_CASE) { - NextToken (); - constexpr (&lval); - if (!IsClassInt (lval.Type)) { - Error ("Switch quantity not an integer"); - } - P = xmalloc (sizeof (SwitchEntry)); - P->Value = lval.ConstVal; - P->Label = GetLocalLabel (); - CollAppend (&SwitchTab, P); - g_defcodelabel (P->Label); - } else if (DefaultLabel == 0) { - NextToken (); - DefaultLabel = GetLocalLabel (); - g_defcodelabel (DefaultLabel); - } else { - /* We already had a default label */ - Error ("Multiple default labels in one switch"); - /* Try to recover */ - NextToken (); - } - ConsumeColon (); - } while (CurTok.Tok == TOK_CASE || CurTok.Tok == TOK_DEFAULT); - HaveBreak = 0; - } - if (CurTok.Tok != TOK_RCURLY) { - HaveBreak = Statement (0); - } - } - - /* Check if we have any labels */ - if (CollCount(&SwitchTab) == 0 && DefaultLabel == 0) { - Warning ("No case labels"); - } - - /* Eat the closing curly brace */ - NextToken (); - - /* If the last statement doesn't have a break or return, add one */ - if (!HaveBreak) { - g_jump (ExitLabel); - } - - /* Actual selector code goes here */ - g_defcodelabel (lcase); - - /* Create the call to the switch subroutine */ - Flags = TypeOf (Expr->Type); - g_switch (Flags); - - /* First entry is negative of label count */ - g_defdata (CF_INT | CF_CONST, -((int)CollCount(&SwitchTab))-1, 0); - - /* Create the case selector table */ - for (I = 0; I < CollCount (&SwitchTab); ++I) { - P = CollAt (&SwitchTab, I); - g_case (Flags, P->Label, P->Value); /* Create one label */ - } - - if (DefaultLabel != 0) { - g_jump (DefaultLabel); - } - g_defcodelabel (ExitLabel); - DelLoop (); - - /* Free the allocated space for the labels */ - for (I = 0; I < CollCount (&SwitchTab); ++I) { - xfree (CollAt (&SwitchTab, I)); - } - - /* Free the collection itself */ - DoneCollection (&SwitchTab); -} - - - -static void SwitchStatement (void) -/* Handle a 'switch' statement */ -{ - ExprDesc Expr; /* Switch statement expression */ - - /* Eat the "switch" */ - NextToken (); - - /* Read the switch expression */ - ConsumeLParen (); - intexpr (&Expr); - ConsumeRParen (); - - /* result of expr is in P */ - ConsumeLCurly (); - - /* Now decide which sort of switch we will create: */ - if (IsTypeChar (Expr.Type) || (CodeSizeFactor >= 200 && IsClassInt (Expr.Type))) { - CascadeSwitch (&Expr); - } else { - TableSwitch (&Expr); - } -} - - - static void ForStatement (void) /* Handle a 'for' statement */ { @@ -849,7 +559,7 @@ int Statement (int* PendingToken) case TOK_PRAGMA: DoPragma (); - break; + break; default: /* Actual statement */ @@ -862,3 +572,4 @@ int Statement (int* PendingToken) + diff --git a/src/cc65/stmt.h b/src/cc65/stmt.h index a5d3abbd4..0a504a0ba 100644 --- a/src/cc65/stmt.h +++ b/src/cc65/stmt.h @@ -1,8 +1,35 @@ -/* - * stmt.h - * - * Ullrich von Bassewitz, 19.06.1998 - */ +/*****************************************************************************/ +/* */ +/* stmt.h */ +/* */ +/* Parse a statement */ +/* */ +/* */ +/* */ +/* (C) 1998-2001 Ullrich von Bassewitz */ +/* Wacholderweg 14 */ +/* D-70597 Stuttgart */ +/* 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. */ +/* */ +/*****************************************************************************/ diff --git a/src/cc65/swstmt.c b/src/cc65/swstmt.c new file mode 100644 index 000000000..05abe0747 --- /dev/null +++ b/src/cc65/swstmt.c @@ -0,0 +1,377 @@ +/*****************************************************************************/ +/* */ +/* swstmt.c */ +/* */ +/* Parse the switch statement */ +/* */ +/* */ +/* */ +/* (C) 1998-2001 Ullrich von Bassewitz */ +/* Wacholderweg 14 */ +/* D-70597 Stuttgart */ +/* 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. */ +/* */ +/*****************************************************************************/ + + + +/* common */ +#include "coll.h" +#include "xmalloc.h" + +/* cc65 */ +#include "asmlabel.h" +#include "codegen.h" +#include "datatype.h" +#include "error.h" +#include "expr.h" +#include "global.h" +#include "loop.h" +#include "scanner.h" +#include "stmt.h" +#include "swstmt.h" + + + +/*****************************************************************************/ +/* Code */ +/*****************************************************************************/ + + + +static void CascadeSwitch (ExprDesc* Expr) +/* Handle a switch statement for chars with a cmp cascade for the selector */ +{ + unsigned ExitLab; /* Exit label */ + unsigned NextLab; /* Next case label */ + unsigned CodeLab; /* Label that starts the actual selector code */ + int HaveBreak; /* Remember if we exited with break */ + int HaveDefault; /* Remember if we had a default label */ + int lcount; /* Label count */ + unsigned Flags; /* Code generator flags */ + ExprDesc lval; /* Case label expression */ + long Val; /* Case label value */ + + + /* Get the unqualified type of the switch expression */ + type ExprType = UnqualifiedType (Expr->Type[0]); + + /* Create a loop so we may break out, init labels */ + ExitLab = GetLocalLabel (); + AddLoop (oursp, 0, ExitLab, 0, 0); + + /* Setup some variables needed in the loop below */ + Flags = TypeOf (Expr->Type) | CF_CONST | CF_FORCECHAR; + CodeLab = NextLab = 0; + HaveBreak = 1; + HaveDefault = 0; + + /* Parse the labels */ + lcount = 0; + while (CurTok.Tok != TOK_RCURLY) { + + if (CurTok.Tok == TOK_CASE || CurTok.Tok == TOK_DEFAULT) { + + /* If the code for the previous selector did not end with a + * break statement, we must jump over the next selector test. + */ + if (!HaveBreak) { + /* Define a label for the code */ + if (CodeLab == 0) { + CodeLab = GetLocalLabel (); + } + g_jump (CodeLab); + } + + /* If we have a cascade label, emit it */ + if (NextLab) { + g_defcodelabel (NextLab); + NextLab = 0; + } + + while (CurTok.Tok == TOK_CASE || CurTok.Tok == TOK_DEFAULT) { + + /* Parse the selector */ + if (CurTok.Tok == TOK_CASE) { + + /* Count labels */ + ++lcount; + + /* Skip the "case" token */ + NextToken (); + + /* Read the selector expression */ + constexpr (&lval); + if (!IsClassInt (lval.Type)) { + Error ("Switch quantity not an integer"); + } + + /* Check the range of the expression */ + Val = lval.ConstVal; + switch (ExprType) { + + case T_SCHAR: + /* Signed char */ + if (Val < -128 || Val > 127) { + Error ("Range error"); + } + break; + + case T_UCHAR: + if (Val < 0 || Val > 255) { + Error ("Range error"); + } + break; + + case T_INT: + if (Val < -32768 || Val > 32767) { + Error ("Range error"); + } + break; + + case T_UINT: + if (Val < 0 || Val > 65535) { + Error ("Range error"); + } + break; + + default: + Internal ("Invalid type: %04X", ExprType); + } + + /* Emit a compare */ + g_cmp (Flags, Val); + + /* If another case follows after the colon (which is + * currently pending and cannot be skipped since otherwise + * the debug infos will get wrong), we will jump to the + * code if the condition is true. + */ + if (NextTok.Tok == TOK_CASE) { + /* Create a code label if needed */ + if (CodeLab == 0) { + CodeLab = GetLocalLabel (); + } + g_falsejump (CF_NONE, CodeLab); + } else if (NextTok.Tok != TOK_DEFAULT) { + /* No case follows, jump to next selector */ + if (NextLab == 0) { + NextLab = GetLocalLabel (); + } + g_truejump (CF_NONE, NextLab); + } + + /* Skip the colon */ + ConsumeColon (); + + } else { + + /* Default case */ + NextToken (); + + /* Handle the pathologic case: DEFAULT followed by CASE */ + if (NextTok.Tok == TOK_CASE) { + if (CodeLab == 0) { + CodeLab = GetLocalLabel (); + } + g_jump (CodeLab); + } + + /* Skip the colon */ + ConsumeColon (); + + /* Remember that we had a default label */ + HaveDefault = 1; + } + + } + + } + + /* Emit a code label if we have one */ + if (CodeLab) { + g_defcodelabel (CodeLab); + CodeLab = 0; + } + + /* Parse statements */ + if (CurTok.Tok != TOK_RCURLY) { + HaveBreak = Statement (0); + } + } + + /* Check if we have any labels */ + if (lcount == 0 && !HaveDefault) { + Warning ("No case labels"); + } + + /* Define the exit label and, if there's a next label left, create this + * one, too. + */ + if (NextLab) { + g_defcodelabel (NextLab); + } + g_defcodelabel (ExitLab); + + /* Eat the closing curly brace */ + NextToken (); + + /* End the loop */ + DelLoop (); +} + + + +static void TableSwitch (ExprDesc* Expr) +/* Handle a switch statement via table based selector */ +{ + /* Entry for one case in a switch statement */ + typedef struct { + long Value; /* selector value */ + unsigned Label; /* label for this selector */ + } SwitchEntry; + + unsigned DefaultLabel; /* Label for default case */ + unsigned ExitLabel; /* exit label */ + int lcase; /* label for compares */ + int HaveBreak; /* Last statement has a break */ + unsigned Flags; /* Code generator flags */ + ExprDesc lval; /* Case label expression */ + unsigned I; + SwitchEntry* P; + Collection SwitchTab; + + /* Initialize the collection for the switch entries */ + InitCollection (&SwitchTab); + + /* Create a look so we may break out, init labels */ + HaveBreak = 0; /* Keep gcc silent */ + DefaultLabel = 0; /* No default case until now */ + ExitLabel = GetLocalLabel (); /* get exit */ + AddLoop (oursp, 0, ExitLabel, 0, 0); + + /* Jump behind the code for the CASE labels */ + g_jump (lcase = GetLocalLabel ()); + while (CurTok.Tok != TOK_RCURLY) { + if (CurTok.Tok == TOK_CASE || CurTok.Tok == TOK_DEFAULT) { + do { + if (CurTok.Tok == TOK_CASE) { + NextToken (); + constexpr (&lval); + if (!IsClassInt (lval.Type)) { + Error ("Switch quantity not an integer"); + } + P = xmalloc (sizeof (SwitchEntry)); + P->Value = lval.ConstVal; + P->Label = GetLocalLabel (); + CollAppend (&SwitchTab, P); + g_defcodelabel (P->Label); + } else if (DefaultLabel == 0) { + NextToken (); + DefaultLabel = GetLocalLabel (); + g_defcodelabel (DefaultLabel); + } else { + /* We already had a default label */ + Error ("Multiple default labels in one switch"); + /* Try to recover */ + NextToken (); + } + ConsumeColon (); + } while (CurTok.Tok == TOK_CASE || CurTok.Tok == TOK_DEFAULT); + HaveBreak = 0; + } + if (CurTok.Tok != TOK_RCURLY) { + HaveBreak = Statement (0); + } + } + + /* Check if we have any labels */ + if (CollCount(&SwitchTab) == 0 && DefaultLabel == 0) { + Warning ("No case labels"); + } + + /* Eat the closing curly brace */ + NextToken (); + + /* If the last statement doesn't have a break or return, add one */ + if (!HaveBreak) { + g_jump (ExitLabel); + } + + /* Actual selector code goes here */ + g_defcodelabel (lcase); + + /* Create the call to the switch subroutine */ + Flags = TypeOf (Expr->Type); + g_switch (Flags); + + /* First entry is negative of label count */ + g_defdata (CF_INT | CF_CONST, -((int)CollCount(&SwitchTab))-1, 0); + + /* Create the case selector table */ + for (I = 0; I < CollCount (&SwitchTab); ++I) { + P = CollAt (&SwitchTab, I); + g_case (Flags, P->Label, P->Value); /* Create one label */ + } + + if (DefaultLabel != 0) { + g_jump (DefaultLabel); + } + g_defcodelabel (ExitLabel); + DelLoop (); + + /* Free the allocated space for the labels */ + for (I = 0; I < CollCount (&SwitchTab); ++I) { + xfree (CollAt (&SwitchTab, I)); + } + + /* Free the collection itself */ + DoneCollection (&SwitchTab); +} + + + +void SwitchStatement (void) +/* Handle a 'switch' statement */ +{ + ExprDesc Expr; /* Switch statement expression */ + + /* Eat the "switch" */ + NextToken (); + + /* Read the switch expression */ + ConsumeLParen (); + intexpr (&Expr); + ConsumeRParen (); + + /* result of expr is in P */ + ConsumeLCurly (); + + /* Now decide which sort of switch we will create: */ + if (IsTypeChar (Expr.Type) || (CodeSizeFactor >= 200 && IsClassInt (Expr.Type))) { + CascadeSwitch (&Expr); + } else { + TableSwitch (&Expr); + } +} + + + diff --git a/src/cc65/swstmt.h b/src/cc65/swstmt.h new file mode 100644 index 000000000..3077d224b --- /dev/null +++ b/src/cc65/swstmt.h @@ -0,0 +1,56 @@ +/*****************************************************************************/ +/* */ +/* swstmt.h */ +/* */ +/* Parse the switch statement */ +/* */ +/* */ +/* */ +/* (C) 1998-2001 Ullrich von Bassewitz */ +/* Wacholderweg 14 */ +/* D-70597 Stuttgart */ +/* 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 SWSTMT_H +#define SWSTMT_H + + + +/*****************************************************************************/ +/* Code */ +/*****************************************************************************/ + + + +void SwitchStatement (void); +/* Handle a 'switch' statement */ + + + +/* End of swstmt.h */ +#endif + + + -- 2.39.5