Renamed some functions for better readbility.
Add a binary search for preprocessor tokens (instead of the old linear one) to speed up the compiler. git-svn-id: svn://svn.cc65.org/cc65/trunk@857 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
parent
bf47ac26c9
commit
e1b0251f04
6 changed files with 158 additions and 143 deletions
|
@ -271,24 +271,24 @@ void Compile (const char* FileName)
|
|||
}
|
||||
|
||||
/* Add macros that are always defined */
|
||||
AddNumericMacro ("__CC65__", (VER_MAJOR * 0x100) + (VER_MINOR * 0x10) + VER_PATCH);
|
||||
DefineNumericMacro ("__CC65__", (VER_MAJOR * 0x100) + (VER_MINOR * 0x10) + VER_PATCH);
|
||||
|
||||
/* Strict ANSI macro */
|
||||
if (ANSI) {
|
||||
AddNumericMacro ("__STRICT_ANSI__", 1);
|
||||
DefineNumericMacro ("__STRICT_ANSI__", 1);
|
||||
}
|
||||
|
||||
/* Optimization macros */
|
||||
if (Optimize) {
|
||||
AddNumericMacro ("__OPT__", 1);
|
||||
DefineNumericMacro ("__OPT__", 1);
|
||||
if (FavourSize == 0) {
|
||||
AddNumericMacro ("__OPT_i__", 1);
|
||||
DefineNumericMacro ("__OPT_i__", 1);
|
||||
}
|
||||
if (EnableRegVars) {
|
||||
AddNumericMacro ("__OPT_r__", 1);
|
||||
DefineNumericMacro ("__OPT_r__", 1);
|
||||
}
|
||||
if (InlineStdFuncs) {
|
||||
AddNumericMacro ("__OPT_s__", 1);
|
||||
DefineNumericMacro ("__OPT_s__", 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -302,7 +302,7 @@ void Compile (const char* FileName)
|
|||
g_preamble ();
|
||||
|
||||
/* Open the input file */
|
||||
OpenMainFile (FileName);
|
||||
OpenMainFile (FileName);
|
||||
|
||||
/* Ok, start the ball rolling... */
|
||||
Parse ();
|
||||
|
|
|
@ -114,8 +114,8 @@ void FreeMacro (Macro* M)
|
|||
|
||||
|
||||
|
||||
void AddNumericMacro (const char* Name, long Val)
|
||||
/* Add a macro for a numeric constant */
|
||||
void DefineNumericMacro (const char* Name, long Val)
|
||||
/* Define a macro for a numeric constant */
|
||||
{
|
||||
char Buf[64];
|
||||
|
||||
|
@ -123,13 +123,13 @@ void AddNumericMacro (const char* Name, long Val)
|
|||
sprintf (Buf, "%ld", Val);
|
||||
|
||||
/* Handle as text macro */
|
||||
AddTextMacro (Name, Buf);
|
||||
DefineTextMacro (Name, Buf);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void AddTextMacro (const char* Name, const char* Val)
|
||||
/* Add a macro for a textual constant */
|
||||
void DefineTextMacro (const char* Name, const char* Val)
|
||||
/* Define a macro for a textual constant */
|
||||
{
|
||||
/* Create a new macro */
|
||||
Macro* M = NewMacro (Name);
|
||||
|
@ -165,7 +165,7 @@ void InsertMacro (Macro* M)
|
|||
/* Increment the number of macros starting with this char */
|
||||
MacroFlagTab[(unsigned)(unsigned char)M->Name[0]]++;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
int UndefineMacro (const char* Name)
|
||||
|
|
|
@ -44,21 +44,21 @@
|
|||
|
||||
|
||||
|
||||
typedef struct Macro_ Macro;
|
||||
struct Macro_ {
|
||||
Macro* Next; /* Next macro with same hash value */
|
||||
int ArgCount; /* Number of parameters, -1 = no parens */
|
||||
typedef struct Macro Macro;
|
||||
struct Macro {
|
||||
Macro* Next; /* Next macro with same hash value */
|
||||
int ArgCount; /* Number of parameters, -1 = no parens */
|
||||
unsigned MaxArgs; /* Size of formal argument list */
|
||||
char** FormalArgs; /* Formal argument list */
|
||||
char const** ActualArgs; /* Actual argument list */
|
||||
char* Replacement; /* Replacement text */
|
||||
char Name[1]; /* Name, dynamically allocated */
|
||||
char Name[1]; /* Name, dynamically allocated */
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* code */
|
||||
/* code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
@ -73,11 +73,11 @@ void FreeMacro (Macro* M);
|
|||
* table, use UndefineMacro for that.
|
||||
*/
|
||||
|
||||
void AddNumericMacro (const char* Name, long Val);
|
||||
/* Add a macro for a numeric constant */
|
||||
void DefineNumericMacro (const char* Name, long Val);
|
||||
/* Define a macro for a numeric constant */
|
||||
|
||||
void AddTextMacro (const char* Name, const char* Val);
|
||||
/* Add a macro for a textual constant */
|
||||
void DefineTextMacro (const char* Name, const char* Val);
|
||||
/* Define a macro for a textual constant */
|
||||
|
||||
void InsertMacro (Macro* M);
|
||||
/* Insert the given macro into the macro table. This call will also allocate
|
||||
|
@ -122,4 +122,3 @@ void PrintMacroStats (FILE* F);
|
|||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -124,8 +124,8 @@ static void Usage (void)
|
|||
static void cbmsys (const char* sys)
|
||||
/* Define a CBM system */
|
||||
{
|
||||
AddNumericMacro ("__CBM__", 1);
|
||||
AddNumericMacro (sys, 1);
|
||||
DefineNumericMacro ("__CBM__", 1);
|
||||
DefineNumericMacro (sys, 1);
|
||||
}
|
||||
|
||||
|
||||
|
@ -139,7 +139,7 @@ static void SetSys (const char* Sys)
|
|||
break;
|
||||
|
||||
case TGT_ATARI:
|
||||
AddNumericMacro ("__ATARI__", 1);
|
||||
DefineNumericMacro ("__ATARI__", 1);
|
||||
break;
|
||||
|
||||
case TGT_C64:
|
||||
|
@ -167,16 +167,16 @@ static void SetSys (const char* Sys)
|
|||
break;
|
||||
|
||||
case TGT_BBC:
|
||||
AddNumericMacro ("__BBC__", 1);
|
||||
DefineNumericMacro ("__BBC__", 1);
|
||||
break;
|
||||
|
||||
case TGT_APPLE2:
|
||||
AddNumericMacro ("__APPLE2__", 1);
|
||||
DefineNumericMacro ("__APPLE2__", 1);
|
||||
break;
|
||||
|
||||
case TGT_GEOS:
|
||||
/* Do not handle as a CBM system */
|
||||
AddNumericMacro ("__GEOS__", 1);
|
||||
DefineNumericMacro ("__GEOS__", 1);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -237,8 +237,8 @@ static void DefineSym (const char* Def)
|
|||
InvDef (Def);
|
||||
}
|
||||
/* No value given. Define the macro with the value 1 */
|
||||
AddNumericMacro (Def, 1);
|
||||
} else {
|
||||
DefineNumericMacro (Def, 1);
|
||||
} else {
|
||||
/* We have a value, P points to the '=' character. Since the argument
|
||||
* is const, create a copy and replace the '=' in the copy by a zero
|
||||
* terminator.
|
||||
|
@ -251,7 +251,7 @@ static void DefineSym (const char* Def)
|
|||
*Q++ = '\0';
|
||||
|
||||
/* Define this as a macro */
|
||||
AddTextMacro (S, Q);
|
||||
DefineTextMacro (S, Q);
|
||||
|
||||
/* Release the allocated memory */
|
||||
xfree (S);
|
||||
|
@ -484,10 +484,10 @@ static void OptIncludeDir (const char* Opt, const char* Arg)
|
|||
|
||||
static void OptListOptSteps (const char* Opt, const char* Arg)
|
||||
/* List all optimizer steps */
|
||||
{
|
||||
{
|
||||
/* List the optimizer steps */
|
||||
ListOptSteps (stdout);
|
||||
|
||||
ListOptSteps (stdout);
|
||||
|
||||
/* Terminate */
|
||||
exit (EXIT_SUCCESS);
|
||||
}
|
||||
|
|
|
@ -39,7 +39,7 @@ static int Pass1 (const char* From, char* To);
|
|||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* data */
|
||||
/* Data */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
@ -63,7 +63,74 @@ static int ExpandMacros = 1;
|
|||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* code */
|
||||
/* Low level preprocessor token handling */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
/* Types of preprocessor tokens */
|
||||
typedef enum {
|
||||
PP_DEFINE,
|
||||
PP_ELSE,
|
||||
PP_ENDIF,
|
||||
PP_ERROR,
|
||||
PP_IF,
|
||||
PP_IFDEF,
|
||||
PP_IFNDEF,
|
||||
PP_INCLUDE,
|
||||
PP_LINE,
|
||||
PP_PRAGMA,
|
||||
PP_UNDEF,
|
||||
PP_ILLEGAL
|
||||
} pptoken_t;
|
||||
|
||||
|
||||
|
||||
/* Preprocessor keyword to token mapping table */
|
||||
static const struct PPToken {
|
||||
const char* Key; /* Keyword */
|
||||
pptoken_t Tok; /* Token */
|
||||
} PPTokens[] = {
|
||||
{ "define", PP_DEFINE },
|
||||
{ "else", PP_ELSE },
|
||||
{ "endif", PP_ENDIF },
|
||||
{ "error", PP_ERROR },
|
||||
{ "if", PP_IF },
|
||||
{ "ifdef", PP_IFDEF },
|
||||
{ "ifndef", PP_IFNDEF },
|
||||
{ "include", PP_INCLUDE },
|
||||
{ "line", PP_LINE },
|
||||
{ "pragma", PP_PRAGMA },
|
||||
{ "undef", PP_UNDEF },
|
||||
};
|
||||
|
||||
/* Number of preprocessor tokens */
|
||||
#define PPTOKEN_COUNT (sizeof(PPTokens) / sizeof(PPTokens[0]))
|
||||
|
||||
|
||||
|
||||
static int CmpToken (const void* Key, const void* Elem)
|
||||
/* Compare function for bsearch */
|
||||
{
|
||||
return strcmp ((const char*) Key, ((const struct PPToken*) Elem)->Key);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static pptoken_t FindPPToken (const char* Ident)
|
||||
/* Find a preprocessor token and return ut. Return PP_ILLEGAL if the identifier
|
||||
* is not a valid preprocessor token.
|
||||
*/
|
||||
{
|
||||
struct PPToken* P;
|
||||
P = bsearch (Ident, PPTokens, PPTOKEN_COUNT, sizeof (PPTokens[0]), CmpToken);
|
||||
return P? P->Tok : PP_ILLEGAL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
@ -166,18 +233,20 @@ static char* CopyQuotedString (char* Target)
|
|||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Macro stuff */
|
||||
/* Macro stuff */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
static int MacName (char* Ident)
|
||||
/* Get macro symbol name. If error, print message and clear line. */
|
||||
/* Get macro symbol name. If we have an error, print a diagnostic message
|
||||
* and clear line.
|
||||
*/
|
||||
{
|
||||
if (IsSym (Ident) == 0) {
|
||||
PPError ("Identifier expected");
|
||||
PPError ("Identifier expected");
|
||||
ClearLine ();
|
||||
return 0;
|
||||
return 0;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
|
@ -186,7 +255,7 @@ static int MacName (char* Ident)
|
|||
|
||||
|
||||
static void ExpandMacroArgs (Macro* M)
|
||||
/* Preprocessor pass 2. Perform macro substitution. */
|
||||
/* Expand the arguments of a macro */
|
||||
{
|
||||
ident Ident;
|
||||
const char* Replacement;
|
||||
|
@ -198,21 +267,21 @@ static void ExpandMacroArgs (Macro* M)
|
|||
|
||||
/* Copy the macro replacement checking for parameters to replace */
|
||||
while (CurC != '\0') {
|
||||
/* If the next token is an identifier, check for a macro arg */
|
||||
/* If the next token is an identifier, check for a macro arg */
|
||||
if (IsIdent (CurC)) {
|
||||
SymName (Ident);
|
||||
Replacement = FindMacroArg (M, Ident);
|
||||
if (Replacement) {
|
||||
/* Macro arg, keep the replacement */
|
||||
Replacement = FindMacroArg (M, Ident);
|
||||
if (Replacement) {
|
||||
/* Macro arg, keep the replacement */
|
||||
keepstr (Replacement);
|
||||
} else {
|
||||
/* No macro argument, keep the original identifier */
|
||||
/* No macro argument, keep the original identifier */
|
||||
keepstr (Ident);
|
||||
}
|
||||
} else if (CurC == '#' && IsIdent (NextC)) {
|
||||
NextChar ();
|
||||
SymName (Ident);
|
||||
Replacement = FindMacroArg (M, Ident);
|
||||
Replacement = FindMacroArg (M, Ident);
|
||||
if (Replacement) {
|
||||
keepch ('\"');
|
||||
keepstr (Replacement);
|
||||
|
@ -225,7 +294,7 @@ static void ExpandMacroArgs (Macro* M)
|
|||
mptr = CopyQuotedString (mptr);
|
||||
} else {
|
||||
*mptr++ = CurC;
|
||||
NextChar ();
|
||||
NextChar ();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -263,68 +332,68 @@ static int MacroCall (Macro* M)
|
|||
B = Buf;
|
||||
while (1) {
|
||||
if (CurC == '(') {
|
||||
/* Nested parenthesis */
|
||||
/* Nested parenthesis */
|
||||
*B++ = CurC;
|
||||
NextChar ();
|
||||
NextChar ();
|
||||
++ParCount;
|
||||
} else if (IsQuote (CurC)) {
|
||||
B = CopyQuotedString (B);
|
||||
} else if (CurC == ',' || CurC == ')') {
|
||||
if (ParCount == 0) {
|
||||
/* End of actual argument */
|
||||
/* End of actual argument */
|
||||
*B++ = '\0';
|
||||
while (IsBlank(*ArgStart)) {
|
||||
++ArgStart;
|
||||
}
|
||||
while (IsBlank(*ArgStart)) {
|
||||
++ArgStart;
|
||||
}
|
||||
if (ArgCount < M->ArgCount) {
|
||||
M->ActualArgs[ArgCount++] = ArgStart;
|
||||
} else if (CurC != ')' || *ArgStart != '\0' || M->ArgCount > 0) {
|
||||
/* Be sure not to count the single empty argument for a
|
||||
* macro that does not have arguments.
|
||||
*/
|
||||
/* Be sure not to count the single empty argument for a
|
||||
* macro that does not have arguments.
|
||||
*/
|
||||
++ArgCount;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check for end of macro param list */
|
||||
if (CurC == ')') {
|
||||
NextChar ();
|
||||
break;
|
||||
}
|
||||
/* Check for end of macro param list */
|
||||
if (CurC == ')') {
|
||||
NextChar ();
|
||||
break;
|
||||
}
|
||||
|
||||
/* Start the next param */
|
||||
ArgStart = B;
|
||||
NextChar ();
|
||||
NextChar ();
|
||||
} else {
|
||||
/* Comma or right paren inside nested parenthesis */
|
||||
/* Comma or right paren inside nested parenthesis */
|
||||
if (CurC == ')') {
|
||||
--ParCount;
|
||||
}
|
||||
*B++ = CurC;
|
||||
NextChar ();
|
||||
NextChar ();
|
||||
}
|
||||
} else if (IsBlank (CurC)) {
|
||||
/* Squeeze runs of blanks */
|
||||
/* Squeeze runs of blanks */
|
||||
*B++ = ' ';
|
||||
SkipBlank ();
|
||||
} else if (CurC == '\0') {
|
||||
/* End of line inside macro argument list - read next line */
|
||||
/* End of line inside macro argument list - read next line */
|
||||
if (NextLine () == 0) {
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
/* Just copy the character */
|
||||
/* Just copy the character */
|
||||
*B++ = CurC;
|
||||
NextChar ();
|
||||
NextChar ();
|
||||
}
|
||||
}
|
||||
|
||||
/* Compare formal argument count with actual */
|
||||
if (M->ArgCount != ArgCount) {
|
||||
PPError ("Macro argument count mismatch");
|
||||
/* Be sure to make enough empty arguments available */
|
||||
while (ArgCount < M->ArgCount) {
|
||||
M->ActualArgs [ArgCount++] = "";
|
||||
}
|
||||
PPError ("Macro argument count mismatch");
|
||||
/* Be sure to make enough empty arguments available */
|
||||
while (ArgCount < M->ArgCount) {
|
||||
M->ActualArgs [ArgCount++] = "";
|
||||
}
|
||||
}
|
||||
|
||||
/* Preprocess the line, replacing macro parameters */
|
||||
|
@ -341,20 +410,20 @@ static void ExpandMacro (Macro* M)
|
|||
{
|
||||
/* Check if this is a function like macro */
|
||||
if (M->ArgCount >= 0) {
|
||||
/* Function like macro */
|
||||
/* Function like macro */
|
||||
if (MacroCall (M) == 0) {
|
||||
ClearLine ();
|
||||
}
|
||||
} else {
|
||||
/* Just copy the replacement text */
|
||||
/* Just copy the replacement text */
|
||||
keepstr (M->Replacement);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void addmac (void)
|
||||
/* Add a macro to the macro table. */
|
||||
static void DefineMacro (void)
|
||||
/* Handle a macro definition. */
|
||||
{
|
||||
char* saveptr;
|
||||
ident Ident;
|
||||
|
@ -381,9 +450,9 @@ static void addmac (void)
|
|||
NextChar ();
|
||||
|
||||
/* Set the marker that this is a function like macro */
|
||||
M->ArgCount = 0;
|
||||
M->ArgCount = 0;
|
||||
|
||||
/* Read the formal parameter list */
|
||||
/* Read the formal parameter list */
|
||||
while (1) {
|
||||
SkipBlank ();
|
||||
if (CurC == ')')
|
||||
|
@ -391,14 +460,14 @@ static void addmac (void)
|
|||
if (MacName (Ident) == 0) {
|
||||
return;
|
||||
}
|
||||
AddMacroArg (M, Ident);
|
||||
AddMacroArg (M, Ident);
|
||||
SkipBlank ();
|
||||
if (CurC != ',')
|
||||
break;
|
||||
NextChar ();
|
||||
}
|
||||
|
||||
/* Check for a right paren and eat it if we find one */
|
||||
/* Check for a right paren and eat it if we find one */
|
||||
if (CurC != ')') {
|
||||
PPError ("`)' expected");
|
||||
ClearLine ();
|
||||
|
@ -425,9 +494,9 @@ static void addmac (void)
|
|||
* Print a diagnostic if not.
|
||||
*/
|
||||
if (Existing) {
|
||||
if (MacroCmp (M, Existing) != 0) {
|
||||
PPError ("Macro redefinition is not identical");
|
||||
}
|
||||
if (MacroCmp (M, Existing) != 0) {
|
||||
PPError ("Macro redefinition is not identical");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -766,51 +835,6 @@ static void doerror (void)
|
|||
|
||||
|
||||
|
||||
/* C preprocessor. */
|
||||
|
||||
/* stuff used to bum the keyword dispatching stuff */
|
||||
enum {
|
||||
PP_DEFINE,
|
||||
PP_ELSE,
|
||||
PP_ENDIF,
|
||||
PP_ERROR,
|
||||
PP_IF,
|
||||
PP_IFDEF,
|
||||
PP_IFNDEF,
|
||||
PP_INCLUDE,
|
||||
PP_LINE,
|
||||
PP_PRAGMA,
|
||||
PP_UNDEF,
|
||||
PP_ILLEGAL
|
||||
};
|
||||
|
||||
static const struct tok_elt pre_toks[] = {
|
||||
{ "define", PP_DEFINE },
|
||||
{ "else", PP_ELSE },
|
||||
{ "endif", PP_ENDIF },
|
||||
{ "error", PP_ERROR },
|
||||
{ "if", PP_IF },
|
||||
{ "ifdef", PP_IFDEF },
|
||||
{ "ifndef", PP_IFNDEF },
|
||||
{ "include", PP_INCLUDE },
|
||||
{ "line", PP_LINE },
|
||||
{ "pragma", PP_PRAGMA },
|
||||
{ "undef", PP_UNDEF },
|
||||
{ 0, PP_ILLEGAL }
|
||||
};
|
||||
|
||||
|
||||
|
||||
static int searchtok (const char *sym, const struct tok_elt *toks)
|
||||
/* Search a token in a table */
|
||||
{
|
||||
while (toks->toknam && strcmp (toks->toknam, sym))
|
||||
++toks;
|
||||
return (toks->toknbr);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void Preprocess (void)
|
||||
/* Preprocess a line */
|
||||
{
|
||||
|
@ -836,11 +860,11 @@ void Preprocess (void)
|
|||
PPError ("Preprocessor directive expected");
|
||||
ClearLine ();
|
||||
} else {
|
||||
switch (searchtok (Directive, pre_toks)) {
|
||||
switch (FindPPToken (Directive)) {
|
||||
|
||||
case PP_DEFINE:
|
||||
if (!Skip) {
|
||||
addmac ();
|
||||
DefineMacro ();
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
|
@ -17,12 +17,6 @@
|
|||
|
||||
|
||||
|
||||
/* Token table entry */
|
||||
struct tok_elt {
|
||||
char *toknam;
|
||||
int toknbr;
|
||||
};
|
||||
|
||||
/* Set when the pp calls expr() recursively */
|
||||
extern unsigned char Preprocessing;
|
||||
|
||||
|
@ -44,5 +38,3 @@ void Preprocess (void);
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue