mirror of
https://github.com/cc65/cc65.git
synced 2025-02-06 12:31:12 +00:00
More renaming. Remove the case label limit by using a collection to store
the switch entries. git-svn-id: svn://svn.cc65.org/cc65/trunk@807 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
parent
c571214513
commit
f249ae345e
@ -231,7 +231,7 @@ static void ParseEnumDecl (void)
|
||||
ExprDesc lval;
|
||||
NextToken ();
|
||||
constexpr (&lval);
|
||||
EnumVal = lval.e_const;
|
||||
EnumVal = lval.ConstVal;
|
||||
}
|
||||
|
||||
/* Add an entry to the symbol table */
|
||||
@ -859,7 +859,7 @@ static void Decl (Declaration* D, unsigned Mode)
|
||||
if (CurTok.Tok != TOK_RBRACK) {
|
||||
ExprDesc lval;
|
||||
constexpr (&lval);
|
||||
Size = lval.e_const;
|
||||
Size = lval.ConstVal;
|
||||
}
|
||||
ConsumeRBrack ();
|
||||
*D->T++ = T_ARRAY;
|
||||
@ -965,9 +965,9 @@ static void ParseVoidInit (void)
|
||||
|
||||
case T_SCHAR:
|
||||
case T_UCHAR:
|
||||
if ((lval.e_flags & E_MCTYPE) == E_TCONST) {
|
||||
if ((lval.Flags & E_MCTYPE) == E_TCONST) {
|
||||
/* Make it byte sized */
|
||||
lval.e_const &= 0xFF;
|
||||
lval.ConstVal &= 0xFF;
|
||||
}
|
||||
DefineData (&lval);
|
||||
break;
|
||||
@ -978,9 +978,9 @@ static void ParseVoidInit (void)
|
||||
case T_UINT:
|
||||
case T_PTR:
|
||||
case T_ARRAY:
|
||||
if ((lval.e_flags & E_MCTYPE) == E_TCONST) {
|
||||
if ((lval.Flags & E_MCTYPE) == E_TCONST) {
|
||||
/* Make it word sized */
|
||||
lval.e_const &= 0xFFFF;
|
||||
lval.ConstVal &= 0xFFFF;
|
||||
}
|
||||
DefineData (&lval);
|
||||
break;
|
||||
@ -1070,9 +1070,9 @@ void ParseInit (type* T)
|
||||
case T_SCHAR:
|
||||
case T_UCHAR:
|
||||
constexpr (&lval);
|
||||
if ((lval.e_flags & E_MCTYPE) == E_TCONST) {
|
||||
if ((lval.Flags & E_MCTYPE) == E_TCONST) {
|
||||
/* Make it byte sized */
|
||||
lval.e_const &= 0xFF;
|
||||
lval.ConstVal &= 0xFF;
|
||||
}
|
||||
assignadjust (T, &lval);
|
||||
DefineData (&lval);
|
||||
@ -1084,9 +1084,9 @@ void ParseInit (type* T)
|
||||
case T_UINT:
|
||||
case T_PTR:
|
||||
constexpr (&lval);
|
||||
if ((lval.e_flags & E_MCTYPE) == E_TCONST) {
|
||||
if ((lval.Flags & E_MCTYPE) == E_TCONST) {
|
||||
/* Make it word sized */
|
||||
lval.e_const &= 0xFFFF;
|
||||
lval.ConstVal &= 0xFFFF;
|
||||
}
|
||||
assignadjust (T, &lval);
|
||||
DefineData (&lval);
|
||||
@ -1095,9 +1095,9 @@ void ParseInit (type* T)
|
||||
case T_LONG:
|
||||
case T_ULONG:
|
||||
constexpr (&lval);
|
||||
if ((lval.e_flags & E_MCTYPE) == E_TCONST) {
|
||||
if ((lval.Flags & E_MCTYPE) == E_TCONST) {
|
||||
/* Make it long sized */
|
||||
lval.e_const &= 0xFFFFFFFF;
|
||||
lval.ConstVal &= 0xFFFFFFFF;
|
||||
}
|
||||
assignadjust (T, &lval);
|
||||
DefineData (&lval);
|
||||
|
486
src/cc65/expr.c
486
src/cc65/expr.c
File diff suppressed because it is too large
Load Diff
@ -46,10 +46,10 @@ typedef struct ExprDesc ExprDesc;
|
||||
struct ExprDesc {
|
||||
struct SymEntry* Sym; /* Symbol table entry if known */
|
||||
type* Type; /* Type array of expression */
|
||||
long e_const; /* Value if expression constant */
|
||||
unsigned short e_flags;
|
||||
unsigned short e_test; /* */
|
||||
unsigned long e_name; /* Name or label number */
|
||||
long ConstVal;/* Value if expression constant */
|
||||
unsigned short Flags;
|
||||
unsigned short Test; /* */
|
||||
unsigned long Name; /* Name or label number */
|
||||
};
|
||||
|
||||
|
||||
|
@ -202,7 +202,7 @@ static void ParseOneDecl (const DeclSpec* Spec)
|
||||
}
|
||||
|
||||
/* Push the value */
|
||||
g_push (flags | TypeOf (Decl.Type), lval.e_const);
|
||||
g_push (flags | TypeOf (Decl.Type), lval.ConstVal);
|
||||
|
||||
/* Mark the variable as referenced */
|
||||
SC |= SC_REF;
|
||||
|
@ -178,7 +178,7 @@ static void FlagPragma (unsigned char* Flag)
|
||||
constexpr (&val);
|
||||
|
||||
/* Store the value into the flag parameter */
|
||||
*Flag = (val.e_const != 0);
|
||||
*Flag = (val.ConstVal != 0);
|
||||
}
|
||||
|
||||
|
||||
|
@ -670,7 +670,7 @@ static int doiff (int skip)
|
||||
NextTok = sv2;
|
||||
|
||||
/* Set the #if condition according to the expression result */
|
||||
return (setmflag (skip, 1, lval.e_const != 0));
|
||||
return (setmflag (skip, 1, lval.ConstVal != 0));
|
||||
}
|
||||
|
||||
|
||||
|
@ -119,14 +119,14 @@ static void StdFunc_strlen (ExprDesc* lval)
|
||||
|
||||
/* Check if the parameter is a const address */
|
||||
unsigned flags = 0;
|
||||
unsigned pflags = pval.e_flags & ~E_MCTYPE;
|
||||
unsigned pflags = pval.Flags & ~E_MCTYPE;
|
||||
if (pflags == E_MCONST) {
|
||||
/* Constant numeric address */
|
||||
flags |= CF_CONST | CF_ABSOLUTE;
|
||||
} else if (k == 0 && ((pflags & E_MGLOBAL) != 0 || pval.e_flags == E_MEOFFS)) {
|
||||
} else if (k == 0 && ((pflags & E_MGLOBAL) != 0 || pval.Flags == E_MEOFFS)) {
|
||||
/* Global array with or without offset */
|
||||
flags |= CF_CONST;
|
||||
if (pval.e_flags & E_TGLAB) {
|
||||
if (pval.Flags & E_TGLAB) {
|
||||
/* External linkage */
|
||||
flags |= CF_EXTERNAL;
|
||||
} else {
|
||||
@ -144,7 +144,7 @@ static void StdFunc_strlen (ExprDesc* lval)
|
||||
assignadjust (ArgType, &pval);
|
||||
|
||||
/* Generate the strlen code */
|
||||
g_strlen (flags, pval.e_name, pval.e_const);
|
||||
g_strlen (flags, pval.Name, pval.ConstVal);
|
||||
|
||||
/* We expect the closing brace */
|
||||
ConsumeRParen ();
|
||||
@ -173,7 +173,7 @@ void HandleStdFunc (ExprDesc* lval)
|
||||
/* Generate code for a known standard function. */
|
||||
{
|
||||
/* Get a pointer to the table entry */
|
||||
struct StdFuncDesc* F = FindFunc ((const char*) lval->e_name);
|
||||
struct StdFuncDesc* F = FindFunc ((const char*) lval->Name);
|
||||
CHECK (F != 0);
|
||||
|
||||
/* Call the handler function */
|
||||
|
100
src/cc65/stmt.c
100
src/cc65/stmt.c
@ -12,6 +12,7 @@
|
||||
#include <string.h>
|
||||
|
||||
/* common */
|
||||
#include "coll.h"
|
||||
#include "xmalloc.h"
|
||||
|
||||
/* cc65 */
|
||||
@ -379,7 +380,7 @@ static void CascadeSwitch (ExprDesc* Expr)
|
||||
}
|
||||
|
||||
/* Check the range of the expression */
|
||||
Val = lval.e_const;
|
||||
Val = lval.ConstVal;
|
||||
switch (*Expr->Type) {
|
||||
|
||||
case T_SCHAR:
|
||||
@ -496,62 +497,58 @@ static void TableSwitch (ExprDesc* Expr)
|
||||
/* Handle a switch statement via table based selector */
|
||||
{
|
||||
/* Entry for one case in a switch statement */
|
||||
struct swent {
|
||||
long sw_const; /* selector value */
|
||||
unsigned sw_lab; /* label for this selector */
|
||||
};
|
||||
typedef struct {
|
||||
long Value; /* selector value */
|
||||
unsigned Label; /* label for this selector */
|
||||
} SwitchEntry;
|
||||
|
||||
int dlabel; /* for default */
|
||||
int lab; /* exit label */
|
||||
int label; /* label for case */
|
||||
unsigned DefaultLabel; /* Label for default case */
|
||||
unsigned ExitLabel; /* exit label */
|
||||
int lcase; /* label for compares */
|
||||
int lcount; /* Label count */
|
||||
int HaveBreak; /* Last statement has a break */
|
||||
int HaveDefault; /* Remember if we had a default label */
|
||||
unsigned Flags; /* Code generator flags */
|
||||
ExprDesc lval; /* Case label expression */
|
||||
struct swent *p;
|
||||
struct swent *swtab;
|
||||
int HaveBreak; /* Last statement has a break */
|
||||
unsigned Flags; /* Code generator flags */
|
||||
ExprDesc lval; /* Case label expression */
|
||||
unsigned I;
|
||||
SwitchEntry* P;
|
||||
Collection SwitchTab;
|
||||
|
||||
/* Allocate memory for the switch table */
|
||||
swtab = xmalloc (CASE_MAX * sizeof (struct swent));
|
||||
/* Initialize the collection for the switch entries */
|
||||
InitCollection (&SwitchTab);
|
||||
|
||||
/* Create a look so we may break out, init labels */
|
||||
HaveBreak = 0; /* Keep gcc silent */
|
||||
HaveDefault = 0; /* No default case until now */
|
||||
dlabel = 0; /* init */
|
||||
lab = GetLocalLabel (); /* get exit */
|
||||
p = swtab;
|
||||
AddLoop (oursp, 0, lab, 0, 0);
|
||||
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 ());
|
||||
lcount = 0;
|
||||
while (CurTok.Tok != TOK_RCURLY) {
|
||||
if (CurTok.Tok == TOK_CASE || CurTok.Tok == TOK_DEFAULT) {
|
||||
if (lcount >= CASE_MAX) {
|
||||
Fatal ("Too many case labels");
|
||||
}
|
||||
label = GetLocalLabel ();
|
||||
do {
|
||||
if (CurTok.Tok == TOK_CASE) {
|
||||
NextToken ();
|
||||
constexpr (&lval);
|
||||
if (!IsClassInt (lval.Type)) {
|
||||
Error ("Switch quantity not an integer");
|
||||
Error ("Switch quantity not an integer");
|
||||
}
|
||||
p->sw_const = lval.e_const;
|
||||
p->sw_lab = label;
|
||||
++p;
|
||||
++lcount;
|
||||
} else {
|
||||
P = xmalloc (sizeof (SwitchEntry));
|
||||
P->Value = lval.ConstVal;
|
||||
P->Label = GetLocalLabel ();
|
||||
CollAppend (&SwitchTab, P);
|
||||
g_defcodelabel (P->Label);
|
||||
} else if (DefaultLabel == 0) {
|
||||
NextToken ();
|
||||
dlabel = label;
|
||||
HaveDefault = 1;
|
||||
}
|
||||
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);
|
||||
g_defcodelabel (label);
|
||||
HaveBreak = 0;
|
||||
}
|
||||
if (CurTok.Tok != TOK_RCURLY) {
|
||||
@ -560,7 +557,7 @@ static void TableSwitch (ExprDesc* Expr)
|
||||
}
|
||||
|
||||
/* Check if we have any labels */
|
||||
if (lcount == 0 && !HaveDefault) {
|
||||
if (CollCount(&SwitchTab) == 0 && DefaultLabel == 0) {
|
||||
Warning ("No case labels");
|
||||
}
|
||||
|
||||
@ -569,7 +566,7 @@ static void TableSwitch (ExprDesc* Expr)
|
||||
|
||||
/* If the last statement doesn't have a break or return, add one */
|
||||
if (!HaveBreak) {
|
||||
g_jump (lab);
|
||||
g_jump (ExitLabel);
|
||||
}
|
||||
|
||||
/* Actual selector code goes here */
|
||||
@ -580,24 +577,27 @@ static void TableSwitch (ExprDesc* Expr)
|
||||
g_switch (Flags);
|
||||
|
||||
/* First entry is negative of label count */
|
||||
g_defdata (CF_INT | CF_CONST, -((int)lcount)-1, 0);
|
||||
g_defdata (CF_INT | CF_CONST, -((int)CollCount(&SwitchTab))-1, 0);
|
||||
|
||||
/* Create the case selector table */
|
||||
p = swtab;
|
||||
while (lcount) {
|
||||
g_case (Flags, p->sw_lab, p->sw_const); /* Create one label */
|
||||
--lcount;
|
||||
++p;
|
||||
for (I = 0; I < CollCount (&SwitchTab); ++I) {
|
||||
P = CollAt (&SwitchTab, I);
|
||||
g_case (Flags, P->Label, P->Value); /* Create one label */
|
||||
}
|
||||
|
||||
if (dlabel) {
|
||||
g_jump (dlabel);
|
||||
if (DefaultLabel != 0) {
|
||||
g_jump (DefaultLabel);
|
||||
}
|
||||
g_defcodelabel (lab);
|
||||
g_defcodelabel (ExitLabel);
|
||||
DelLoop ();
|
||||
|
||||
/* Free the allocated space for the labels */
|
||||
xfree (swtab);
|
||||
for (I = 0; I < CollCount (&SwitchTab); ++I) {
|
||||
xfree (CollAt (&SwitchTab, I));
|
||||
}
|
||||
|
||||
/* Free the collection itself */
|
||||
DoneCollection (&SwitchTab);
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user