From 0e80187cec763daaf02a3dae725233c6885cf41a Mon Sep 17 00:00:00 2001 From: cuz Date: Tue, 22 May 2001 09:32:24 +0000 Subject: [PATCH] Added the lineinfo module. Changed the complete code generation to use the supplied data structures. Re-added the -T option which is much more exact now because of the better line info stuff. Cleanups in the scanner (remove old #defines). git-svn-id: svn://svn.cc65.org/cc65/trunk@740 b7a2c559-68d2-44c3-8de9-860c34a00d81 --- src/cc65/codeent.c | 25 +++---- src/cc65/codeent.h | 32 +++++---- src/cc65/codeopt.c | 31 ++++---- src/cc65/codeseg.c | 69 +++++++----------- src/cc65/codeseg.h | 6 +- src/cc65/compile.c | 23 +++--- src/cc65/coptind.c | 13 ++-- src/cc65/declare.c | 103 +++++++++++++-------------- src/cc65/error.c | 30 ++++++-- src/cc65/expr.c | 97 +++++++++++++------------- src/cc65/function.c | 4 +- src/cc65/goto.c | 2 +- src/cc65/input.c | 29 ++------ src/cc65/input.h | 12 ++++ src/cc65/lineinfo.c | 159 ++++++++++++++++++++++++++++++++++++++++++ src/cc65/lineinfo.h | 106 ++++++++++++++++++++++++++++ src/cc65/locals.c | 10 +-- src/cc65/make/gcc.mak | 1 + src/cc65/pragma.c | 14 ++-- src/cc65/scanner.c | 145 ++++++++++++++++++++++++-------------- src/cc65/scanner.h | 64 +++++++++++------ src/cc65/segments.c | 3 +- src/cc65/stmt.c | 72 +++++++++---------- 23 files changed, 693 insertions(+), 357 deletions(-) create mode 100644 src/cc65/lineinfo.c create mode 100644 src/cc65/lineinfo.h diff --git a/src/cc65/codeent.c b/src/cc65/codeent.c index c96a95ef8..ead59afaf 100644 --- a/src/cc65/codeent.c +++ b/src/cc65/codeent.c @@ -160,7 +160,8 @@ static void SetUseChgInfo (CodeEntry* E, const OPCDesc* D) -CodeEntry* NewCodeEntry (opc_t OPC, am_t AM, const char* Arg, CodeLabel* JumpTo) +CodeEntry* NewCodeEntry (opc_t OPC, am_t AM, const char* Arg, + CodeLabel* JumpTo, LineInfo* LI) /* Create a new code entry, initialize and return it */ { /* Get the opcode description */ @@ -170,18 +171,14 @@ CodeEntry* NewCodeEntry (opc_t OPC, am_t AM, const char* Arg, CodeLabel* JumpTo) CodeEntry* E = xmalloc (sizeof (CodeEntry)); /* Initialize the fields */ - E->OPC = D->OPC; - E->AM = AM; - E->Size = GetInsnSize (E->OPC, E->AM); - E->Hints = 0; - E->Arg = GetArgCopy (Arg); - if (NumArg (E->Arg, &E->Num)) { - E-> Flags = CEF_NUMARG; - } else { - E->Flags = 0; - } + E->OPC = D->OPC; + E->AM = AM; + E->Arg = GetArgCopy (Arg); + E->Flags = NumArg (E->Arg, &E->Num)? CEF_NUMARG : 0; + E->Size = GetInsnSize (E->OPC, E->AM); E->Info = D->Info; E->JumpTo = JumpTo; + E->LI = UseLineInfo (LI); SetUseChgInfo (E, D); InitCollection (&E->Labels); @@ -205,6 +202,9 @@ void FreeCodeEntry (CodeEntry* E) /* Cleanup the collection */ DoneCollection (&E->Labels); + /* Release the line info */ + ReleaseLineInfo (E->LI); + /* Free the entry */ xfree (E); } @@ -359,7 +359,7 @@ void OutputCodeEntry (const CodeEntry* E, FILE* F) /* Print usage info if requested by the debugging flag */ // if (Debug) { Chars += fprintf (F, - "%*s; USE: %c%c%c CHG: %c%c%c SIZE: %u", + "%*s; USE: %c%c%c CHG: %c%c%c SIZE: %u\n", 30-Chars, "", (E->Use & REG_A)? 'A' : '_', (E->Use & REG_X)? 'X' : '_', @@ -375,3 +375,4 @@ void OutputCodeEntry (const CodeEntry* E, FILE* F) + diff --git a/src/cc65/codeent.h b/src/cc65/codeent.h index 4c37eeb4f..4de91b0d1 100644 --- a/src/cc65/codeent.h +++ b/src/cc65/codeent.h @@ -46,35 +46,36 @@ /* cc65 */ #include "codelab.h" +#include "lineinfo.h" #include "opcodes.h" /*****************************************************************************/ -/* Data */ +/* Data */ /*****************************************************************************/ /* Flags used */ -#define CEF_USERMARK 0x0001U /* Generic mark by user functions */ -#define CEF_NUMARG 0x0002U /* Insn has numerical argument */ +#define CEF_USERMARK 0x0001U /* Generic mark by user functions */ +#define CEF_NUMARG 0x0002U /* Insn has numerical argument */ /* Code entry structure */ typedef struct CodeEntry CodeEntry; struct CodeEntry { - opc_t OPC; /* Opcode */ - am_t AM; /* Adressing mode */ - unsigned char Size; /* Estimated size */ - unsigned char Hints; /* Hints for this entry */ + opc_t OPC; /* Opcode */ + am_t AM; /* Adressing mode */ char* Arg; /* Argument as string */ - unsigned long Num; /* Numeric argument */ - unsigned short Flags; /* Flags */ - unsigned char Info; /* Additional code info */ - unsigned char Use; /* Registers used */ - unsigned char Chg; /* Registers changed/destroyed */ - CodeLabel* JumpTo; /* Jump label */ - Collection Labels; /* Labels for this instruction */ + unsigned long Num; /* Numeric argument */ + unsigned short Flags; /* Flags */ + unsigned char Size; /* Estimated size */ + unsigned char Info; /* Additional code info */ + unsigned char Use; /* Registers used */ + unsigned char Chg; /* Registers changed/destroyed */ + CodeLabel* JumpTo; /* Jump label */ + Collection Labels; /* Labels for this instruction */ + LineInfo* LI; /* Source line info for this insn */ }; @@ -85,7 +86,8 @@ struct CodeEntry { -CodeEntry* NewCodeEntry (opc_t OPC, am_t AM, const char* Arg, CodeLabel* JumpTo); +CodeEntry* NewCodeEntry (opc_t OPC, am_t AM, const char* Arg, + CodeLabel* JumpTo, LineInfo* LI); /* Create a new code entry, initialize and return it */ void FreeCodeEntry (CodeEntry* E); diff --git a/src/cc65/codeopt.c b/src/cc65/codeopt.c index 4590bb57c..01dd4b471 100644 --- a/src/cc65/codeopt.c +++ b/src/cc65/codeopt.c @@ -185,7 +185,7 @@ static void ReplaceCmp (CodeSeg* S, unsigned I, cmp_t Cond) Internal ("Invalid program flow"); } L = GenCodeLabel (S, N); - N = NewCodeEntry (OPC_BEQ, AM_BRA, L->Name, L); + N = NewCodeEntry (OPC_BEQ, AM_BRA, L->Name, L, E->LI); InsertCodeEntry (S, N, I); ReplaceOPC (E, OPC_JPL); break; @@ -205,7 +205,7 @@ static void ReplaceCmp (CodeSeg* S, unsigned I, cmp_t Cond) */ ReplaceOPC (E, OPC_JMI); L = E->JumpTo; - N = NewCodeEntry (OPC_JEQ, AM_BRA, L->Name, L); + N = NewCodeEntry (OPC_JEQ, AM_BRA, L->Name, L, E->LI); InsertCodeEntry (S, N, I+1); break; @@ -220,7 +220,7 @@ static void ReplaceCmp (CodeSeg* S, unsigned I, cmp_t Cond) Internal ("Invalid program flow"); } L = GenCodeLabel (S, N); - N = NewCodeEntry (OPC_BEQ, AM_BRA, L->Name, L); + N = NewCodeEntry (OPC_BEQ, AM_BRA, L->Name, L, E->LI); InsertCodeEntry (S, N, I); ReplaceOPC (E, OPC_JCS); break; @@ -240,7 +240,7 @@ static void ReplaceCmp (CodeSeg* S, unsigned I, cmp_t Cond) */ ReplaceOPC (E, OPC_JCC); L = E->JumpTo; - N = NewCodeEntry (OPC_JEQ, AM_BRA, L->Name, L); + N = NewCodeEntry (OPC_JEQ, AM_BRA, L->Name, L, E->LI); InsertCodeEntry (S, N, I+1); break; @@ -645,7 +645,7 @@ static unsigned OptCmp1 (CodeSeg* S) DelCodeEntries (S, I+1, 2); /* Insert the ora instead */ - InsertCodeEntry (S, NewCodeEntry (OPC_ORA, E->AM, E->Arg, 0), I+1); + InsertCodeEntry (S, NewCodeEntry (OPC_ORA, E->AM, E->Arg, 0, E->LI), I+1); /* Remember, we had changes */ ++Changes; @@ -893,9 +893,9 @@ static unsigned OptCmp5 (CodeSeg* S) } /* Replace the subroutine call. */ + E = NewCodeEntry (OPC_JSR, AM_ABS, "tosicmp", 0, E->LI); + InsertCodeEntry (S, E, I+1); DelCodeEntry (S, I); - E = NewCodeEntry (OPC_JSR, AM_ABS, "tosicmp", 0); - InsertCodeEntry (S, E, I); /* Replace the conditional branch */ ReplaceCmp (S, I+1, Cond); @@ -1197,22 +1197,27 @@ static unsigned OptNegAX3 (CodeSeg* S) !CodeEntryHasLabel (L[0]) && (L[1]->Info & OF_ZBRA) != 0) { + CodeEntry* X; + /* Check if we're calling bnega or bnegax */ int ByteSized = (strcmp (L[0]->Arg, "bnega") == 0); - /* Delete the subroutine call */ - DelCodeEntry (S, I+1); - /* Insert apropriate test code */ if (ByteSized) { /* Test bytes */ - InsertCodeEntry (S, NewCodeEntry (OPC_TAX, AM_IMP, 0, 0), I+1); + X = NewCodeEntry (OPC_TAX, AM_IMP, 0, 0, L[0]->LI); + InsertCodeEntry (S, X, I+2); } else { /* Test words */ - InsertCodeEntry (S, NewCodeEntry (OPC_STX, AM_ZP, "tmp1", 0), I+1); - InsertCodeEntry (S, NewCodeEntry (OPC_ORA, AM_ZP, "tmp1", 0), I+2); + X = NewCodeEntry (OPC_STX, AM_ZP, "tmp1", 0, L[0]->LI); + InsertCodeEntry (S, X, I+2); + X = NewCodeEntry (OPC_ORA, AM_ZP, "tmp1", 0, L[0]->LI); + InsertCodeEntry (S, X, I+3); } + /* Delete the subroutine call */ + DelCodeEntry (S, I+1); + /* Invert the branch */ ReplaceOPC (L[1], GetInverseBranch (L[1]->OPC)); diff --git a/src/cc65/codeseg.c b/src/cc65/codeseg.c index d378d2595..57bf95cec 100644 --- a/src/cc65/codeseg.c +++ b/src/cc65/codeseg.c @@ -39,6 +39,7 @@ /* common */ #include "chartype.h" #include "check.h" +#include "global.h" #include "hashstr.h" #include "strutil.h" #include "xmalloc.h" @@ -184,7 +185,7 @@ static const char* ReadToken (const char* L, const char* Term, -static CodeEntry* ParseInsn (CodeSeg* S, const char* L) +static CodeEntry* ParseInsn (CodeSeg* S, LineInfo* LI, const char* L) /* Parse an instruction nnd generate a code entry from it. If the line contains * errors, output an error message and return NULL. * For simplicity, we don't accept the broad range of input a "real" assembler @@ -356,7 +357,7 @@ static CodeEntry* ParseInsn (CodeSeg* S, const char* L) /* We do now have the addressing mode in AM. Allocate a new CodeEntry * structure and initialize it. */ - E = NewCodeEntry (OPC->OPC, AM, Arg, Label); + E = NewCodeEntry (OPC->OPC, AM, Arg, Label, LI); /* Return the new code entry */ return E; @@ -365,7 +366,7 @@ static CodeEntry* ParseInsn (CodeSeg* S, const char* L) /*****************************************************************************/ -/* Code */ +/* Code */ /*****************************************************************************/ @@ -402,7 +403,7 @@ CodeSeg* NewCodeSeg (const char* SegName, SymEntry* Func) -void AddCodeEntry (CodeSeg* S, const char* Format, va_list ap) +void AddCodeEntry (CodeSeg* S, LineInfo* LI, const char* Format, va_list ap) /* Add a line to the given code segment */ { const char* L; @@ -435,7 +436,7 @@ void AddCodeEntry (CodeSeg* S, const char* Format, va_list ap) break; default: - E = ParseInsn (S, L); + E = ParseInsn (S, LI, L); break; } @@ -855,26 +856,6 @@ void MoveCodeLabelRef (CodeSeg* S, struct CodeEntry* E, CodeLabel* L) -void AddCodeSegHint (CodeSeg* S, unsigned Hint) -/* Add a hint for the preceeding instruction */ -{ - CodeEntry* E; - - /* Get the number of entries in this segment */ - unsigned EntryCount = GetCodeEntryCount (S); - - /* Must have at least one entry */ - CHECK (EntryCount > 0); - - /* Get the last entry */ - E = GetCodeEntry (S, EntryCount-1); - - /* Add the hint */ - E->Hints |= Hint; -} - - - void DelCodeSegAfter (CodeSeg* S, unsigned Last) /* Delete all entries including the given one */ { @@ -939,6 +920,7 @@ void OutputCodeSeg (const CodeSeg* S, FILE* F) /* Output the code segment data to a file */ { unsigned I; + const LineInfo* LI; /* Get the number of entries in this segment */ unsigned Count = GetCodeEntryCount (S); @@ -956,24 +938,27 @@ void OutputCodeSeg (const CodeSeg* S, FILE* F) fprintf (F, ".proc\t_%s\n\n", S->Func->Name); } - /* Output all entries */ + /* Output all entries, prepended by the line information if it has changed */ + LI = 0; for (I = 0; I < Count; ++I) { - - unsigned char Use; - - OutputCodeEntry (CollConstAt (&S->Entries, I), F); - -#if 0 - /* Print usage info */ - Use = GetRegInfo ((CodeSeg*) S, I+1); - fprintf (F, - " Use: %c%c%c\n", - (Use & REG_A)? 'A' : '_', - (Use & REG_X)? 'X' : '_', - (Use & REG_Y)? 'Y' : '_'); -#else - fprintf (F, "\n"); -#endif + /* Get the next entry */ + const CodeEntry* E = CollConstAt (&S->Entries, I); + /* Check if the line info has changed. If so, output the source line + * if the option is enabled. + */ + if (E->LI != LI) { + LI = E->LI; + if (AddSource) { + /* Skip spaces to make the output somewhat more readable */ + const char* Line = LI->Line; + while (IsBlank (*Line)) { + ++Line; + } + fprintf (F, ";\n; %s\n;\n", Line); + } + } + /* Output the code */ + OutputCodeEntry (E, F); } /* If this is a segment for a function, leave the function */ diff --git a/src/cc65/codeseg.h b/src/cc65/codeseg.h index 3fce28158..b41faa925 100644 --- a/src/cc65/codeseg.h +++ b/src/cc65/codeseg.h @@ -48,6 +48,7 @@ /* cc65 */ #include "codelab.h" +#include "lineinfo.h" #include "symentry.h" @@ -93,7 +94,7 @@ struct CodeSeg { CodeSeg* NewCodeSeg (const char* SegName, SymEntry* Func); /* Create a new code segment, initialize and return it */ -void AddCodeEntry (CodeSeg* S, const char* Format, va_list ap) attribute ((format(printf,2,0))); +void AddCodeEntry (CodeSeg* S, LineInfo* LI, const char* Format, va_list ap) attribute ((format(printf,3,0))); /* Add a line to the given code segment */ void InsertCodeEntry (CodeSeg* S, struct CodeEntry* E, unsigned Index); @@ -177,9 +178,6 @@ void MoveCodeLabelRef (CodeSeg* S, struct CodeEntry* E, CodeLabel* L); * deleted. */ -void AddCodeSegHint (CodeSeg* S, unsigned Hint); -/* Add a hint for the preceeding instruction */ - void DelCodeSegAfter (CodeSeg* S, unsigned Last); /* Delete all entries including the given one */ diff --git a/src/cc65/compile.c b/src/cc65/compile.c index 8a57fa040..6d0e88ceb 100644 --- a/src/cc65/compile.c +++ b/src/cc65/compile.c @@ -56,7 +56,7 @@ /*****************************************************************************/ -/* Code */ +/* Code */ /*****************************************************************************/ @@ -67,29 +67,32 @@ static void Parse (void) int comma; SymEntry* Entry; - NextToken (); /* "prime" the pump */ + /* Go... */ NextToken (); - while (curtok != TOK_CEOF) { + NextToken (); + + /* Parse until end of input */ + while (CurTok.Tok != TOK_CEOF) { DeclSpec Spec; Declaration Decl; int NeedStorage; /* Check for empty statements */ - if (curtok == TOK_SEMI) { + if (CurTok.Tok == TOK_SEMI) { NextToken (); continue; } /* Check for an ASM statement (which is allowed also on global level) */ - if (curtok == TOK_ASM) { + if (CurTok.Tok == TOK_ASM) { doasm (); ConsumeSemi (); continue; } /* Check for a #pragma */ - if (curtok == TOK_PRAGMA) { + if (CurTok.Tok == TOK_PRAGMA) { DoPragma (); continue; } @@ -104,7 +107,7 @@ static void Parse (void) } /* Check if this is only a type declaration */ - if (curtok == TOK_SEMI) { + if (CurTok.Tok == TOK_SEMI) { CheckEmptyDecl (&Spec); NextToken (); continue; @@ -155,7 +158,7 @@ static void Parse (void) unsigned Size = SizeOf (Decl.Type); /* Allow initialization */ - if (curtok == TOK_ASSIGN) { + if (CurTok.Tok == TOK_ASSIGN) { /* We cannot initialize types of unknown size, or * void types in non ANSI mode. @@ -210,7 +213,7 @@ static void Parse (void) } /* Check for end of declaration list */ - if (curtok == TOK_COMMA) { + if (CurTok.Tok == TOK_COMMA) { NextToken (); comma = 1; } else { @@ -224,7 +227,7 @@ static void Parse (void) /* Function */ if (!comma) { - if (curtok == TOK_SEMI) { + if (CurTok.Tok == TOK_SEMI) { /* Prototype only */ NextToken (); diff --git a/src/cc65/coptind.c b/src/cc65/coptind.c index 2f8951ec2..035a4852e 100644 --- a/src/cc65/coptind.c +++ b/src/cc65/coptind.c @@ -67,12 +67,13 @@ unsigned OptRTSJumps (CodeSeg* S) E->JumpTo != 0 && E->JumpTo->Owner->OPC == OPC_RTS) { + /* Insert an RTS instruction */ + CodeEntry* X = NewCodeEntry (OPC_RTS, AM_IMP, 0, 0, E->LI); + InsertCodeEntry (S, X, I+1); + /* Delete the jump */ DelCodeEntry (S, I); - /* Insert an RTS instruction instead */ - InsertCodeEntry (S, NewCodeEntry (OPC_RTS, AM_IMP, 0, 0), I); - /* Remember, we had changes */ ++Changes; @@ -248,7 +249,7 @@ unsigned OptJumpCascades (CodeSeg* S) /* This is a jump cascade and we may jump to the final target. * Insert a new instruction, then remove the old one */ - CodeEntry* X = NewCodeEntry (E->OPC, E->AM, N->Arg, N->JumpTo); + CodeEntry* X = NewCodeEntry (E->OPC, E->AM, N->Arg, N->JumpTo, E->LI); /* Insert it behind E */ InsertCodeEntry (S, X, I+1); @@ -284,8 +285,8 @@ unsigned OptJumpCascades (CodeSeg* S) goto NextEntry; } - /* We may jump behind this conditional branch. Get the - * pointer to the next instruction + /* We may jump behind this conditional branch. Get the + * pointer to the next instruction */ if ((X = GetNextCodeEntry (S, GetCodeEntryIndex (S, N))) == 0) { /* N is the last entry, bail out */ diff --git a/src/cc65/declare.c b/src/cc65/declare.c index 3ef54e059..c3ebf482b 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -78,9 +78,9 @@ static void ParseTypeSpec (DeclSpec* D, int Default); static type OptionalQualifiers (type Q) /* Read type qualifiers if we have any */ { - while (curtok == TOK_CONST || curtok == TOK_VOLATILE) { + while (CurTok.Tok == TOK_CONST || CurTok.Tok == TOK_VOLATILE) { - switch (curtok) { + switch (CurTok.Tok) { case TOK_CONST: if (Q & T_QUAL_CONST) { @@ -115,7 +115,7 @@ static type OptionalQualifiers (type Q) static void optionalint (void) /* Eat an optional "int" token */ { - if (curtok == TOK_INT) { + if (CurTok.Tok == TOK_INT) { /* Skip it */ NextToken (); } @@ -126,7 +126,7 @@ static void optionalint (void) static void optionalsigned (void) /* Eat an optional "signed" token */ { - if (curtok == TOK_SIGNED) { + if (CurTok.Tok == TOK_SIGNED) { /* Skip it */ NextToken (); } @@ -161,7 +161,7 @@ static void ParseStorageClass (DeclSpec* D, unsigned DefStorage) D->Flags &= ~DS_DEF_STORAGE; /* Check the storage class given */ - switch (curtok) { + switch (CurTok.Tok) { case TOK_EXTERN: D->StorageClass = SC_EXTERN | SC_STATIC; @@ -205,7 +205,7 @@ static void ParseEnumDecl (void) ident Ident; /* Accept forward definitions */ - if (curtok != TOK_LCURLY) { + if (CurTok.Tok != TOK_LCURLY) { return; } @@ -214,10 +214,10 @@ static void ParseEnumDecl (void) /* Read the enum tags */ EnumVal = 0; - while (curtok != TOK_RCURLY) { + while (CurTok.Tok != TOK_RCURLY) { /* We expect an identifier */ - if (curtok != TOK_IDENT) { + if (CurTok.Tok != TOK_IDENT) { Error ("Identifier expected"); continue; } @@ -227,7 +227,7 @@ static void ParseEnumDecl (void) NextToken (); /* Check for an assigned value */ - if (curtok == TOK_ASSIGN) { + if (CurTok.Tok == TOK_ASSIGN) { struct expent lval; NextToken (); constexpr (&lval); @@ -238,7 +238,7 @@ static void ParseEnumDecl (void) AddConstSym (Ident, type_int, SC_ENUM, EnumVal++); /* Check for end of definition */ - if (curtok != TOK_COMMA) + if (CurTok.Tok != TOK_COMMA) break; NextToken (); } @@ -257,7 +257,7 @@ static SymEntry* ParseStructDecl (const char* Name, type StructType) SymEntry* Entry; - if (curtok != TOK_LCURLY) { + if (CurTok.Tok != TOK_LCURLY) { /* Just a forward declaration. Try to find a struct with the given * name. If there is none, insert a forward declaration into the * current lexical level. @@ -283,7 +283,7 @@ static SymEntry* ParseStructDecl (const char* Name, type StructType) /* Parse struct fields */ Size = 0; - while (curtok != TOK_RCURLY) { + while (CurTok.Tok != TOK_RCURLY) { /* Get the type of the entry */ DeclSpec Spec; @@ -310,7 +310,7 @@ static SymEntry* ParseStructDecl (const char* Name, type StructType) } } - if (curtok != TOK_COMMA) + if (CurTok.Tok != TOK_COMMA) break; NextToken (); } @@ -345,7 +345,7 @@ static void ParseTypeSpec (DeclSpec* D, int Default) Qualifiers = OptionalQualifiers (T_QUAL_NONE); /* Look at the data type */ - switch (curtok) { + switch (CurTok.Tok) { case TOK_VOID: NextToken (); @@ -361,7 +361,7 @@ static void ParseTypeSpec (DeclSpec* D, int Default) case TOK_LONG: NextToken (); - if (curtok == TOK_UNSIGNED) { + if (CurTok.Tok == TOK_UNSIGNED) { NextToken (); optionalint (); D->Type[0] = T_ULONG; @@ -376,7 +376,7 @@ static void ParseTypeSpec (DeclSpec* D, int Default) case TOK_SHORT: NextToken (); - if (curtok == TOK_UNSIGNED) { + if (CurTok.Tok == TOK_UNSIGNED) { NextToken (); optionalint (); D->Type[0] = T_USHORT; @@ -397,7 +397,7 @@ static void ParseTypeSpec (DeclSpec* D, int Default) case TOK_SIGNED: NextToken (); - switch (curtok) { + switch (CurTok.Tok) { case TOK_CHAR: NextToken (); @@ -432,7 +432,7 @@ static void ParseTypeSpec (DeclSpec* D, int Default) case TOK_UNSIGNED: NextToken (); - switch (curtok) { + switch (CurTok.Tok) { case TOK_CHAR: NextToken (); @@ -467,10 +467,10 @@ static void ParseTypeSpec (DeclSpec* D, int Default) case TOK_STRUCT: case TOK_UNION: - StructType = (curtok == TOK_STRUCT)? T_STRUCT : T_UNION; + StructType = (CurTok.Tok == TOK_STRUCT)? T_STRUCT : T_UNION; NextToken (); /* */ - if (curtok == TOK_IDENT) { + if (CurTok.Tok == TOK_IDENT) { strcpy (Ident, CurTok.Ident); NextToken (); } else { @@ -488,9 +488,9 @@ static void ParseTypeSpec (DeclSpec* D, int Default) case TOK_ENUM: NextToken (); - if (curtok != TOK_LCURLY) { + if (CurTok.Tok != TOK_LCURLY) { /* Named enum */ - if (curtok == TOK_IDENT) { + if (CurTok.Tok == TOK_IDENT) { /* Find an entry with this name */ Entry = FindTagSym (CurTok.Ident); if (Entry) { @@ -561,10 +561,10 @@ static void ParseOldStyleParamList (FuncDesc* F) /* Parse an old style (K&R) parameter list */ { /* Parse params */ - while (curtok != TOK_RPAREN) { + while (CurTok.Tok != TOK_RPAREN) { /* List of identifiers expected */ - if (curtok != TOK_IDENT) { + if (CurTok.Tok != TOK_IDENT) { Error ("Identifier expected"); } @@ -578,7 +578,7 @@ static void ParseOldStyleParamList (FuncDesc* F) NextToken (); /* Check for more parameters */ - if (curtok == TOK_COMMA) { + if (CurTok.Tok == TOK_COMMA) { NextToken (); } else { break; @@ -591,7 +591,7 @@ static void ParseOldStyleParamList (FuncDesc* F) ConsumeRParen (); /* An optional list of type specifications follows */ - while (curtok != TOK_LCURLY) { + while (CurTok.Tok != TOK_LCURLY) { DeclSpec Spec; @@ -625,7 +625,7 @@ static void ParseOldStyleParamList (FuncDesc* F) } } - if (curtok == TOK_COMMA) { + if (CurTok.Tok == TOK_COMMA) { NextToken (); } else { break; @@ -644,14 +644,14 @@ static void ParseAnsiParamList (FuncDesc* F) /* Parse a new style (ANSI) parameter list */ { /* Parse params */ - while (curtok != TOK_RPAREN) { + while (CurTok.Tok != TOK_RPAREN) { DeclSpec Spec; Declaration Decl; DeclAttr Attr; /* Allow an ellipsis as last parameter */ - if (curtok == TOK_ELLIPSIS) { + if (CurTok.Tok == TOK_ELLIPSIS) { NextToken (); F->Flags |= FD_VARIADIC; break; @@ -695,7 +695,7 @@ static void ParseAnsiParamList (FuncDesc* F) ++F->ParamCount; /* Check for more parameters */ - if (curtok == TOK_COMMA) { + if (CurTok.Tok == TOK_COMMA) { NextToken (); } else { break; @@ -708,7 +708,7 @@ static void ParseAnsiParamList (FuncDesc* F) ConsumeRParen (); /* Check if this is a function definition */ - if (curtok == TOK_LCURLY) { + if (CurTok.Tok == TOK_LCURLY) { /* Print an error if in strict ANSI mode and we have unnamed * parameters. */ @@ -733,14 +733,15 @@ static FuncDesc* ParseFuncDecl (void) EnterFunctionLevel (); /* Check for several special parameter lists */ - if (curtok == TOK_RPAREN) { + if (CurTok.Tok == TOK_RPAREN) { /* Parameter list is empty */ F->Flags |= (FD_EMPTY | FD_VARIADIC); - } else if (curtok == TOK_VOID && nxttok == TOK_RPAREN) { + } else if (CurTok.Tok == TOK_VOID && NextTok.Tok == TOK_RPAREN) { /* Parameter list declared as void */ NextToken (); F->Flags |= FD_VOID_PARAM; - } else if (curtok == TOK_IDENT && (nxttok == TOK_COMMA || nxttok == TOK_RPAREN)) { + } else if (CurTok.Tok == TOK_IDENT && + (NextTok.Tok == TOK_COMMA || NextTok.Tok == TOK_RPAREN)) { /* If the identifier is a typedef, we have a new style parameter list, * if it's some other identifier, it's an old style parameter list. */ @@ -786,7 +787,7 @@ static void Decl (Declaration* D, unsigned Mode) /* Recursively process declarators. Build a type array in reverse order. */ { - if (curtok == TOK_STAR) { + if (CurTok.Tok == TOK_STAR) { type T = T_PTR; NextToken (); /* Allow optional const or volatile qualifiers */ @@ -794,11 +795,11 @@ static void Decl (Declaration* D, unsigned Mode) Decl (D, Mode); *D->T++ = T; return; - } else if (curtok == TOK_LPAREN) { + } else if (CurTok.Tok == TOK_LPAREN) { NextToken (); Decl (D, Mode); ConsumeRParen (); - } else if (curtok == TOK_FASTCALL) { + } else if (CurTok.Tok == TOK_FASTCALL) { /* Remember the current type pointer */ type* T = D->T; /* Skip the fastcall token */ @@ -828,7 +829,7 @@ static void Decl (Declaration* D, unsigned Mode) */ if (Mode == DM_NO_IDENT) { D->Ident[0] = '\0'; - } else if (curtok == TOK_IDENT) { + } else if (CurTok.Tok == TOK_IDENT) { strcpy (D->Ident, CurTok.Ident); NextToken (); } else { @@ -840,8 +841,8 @@ static void Decl (Declaration* D, unsigned Mode) } } - while (curtok == TOK_LBRACK || curtok == TOK_LPAREN) { - if (curtok == TOK_LPAREN) { + while (CurTok.Tok == TOK_LBRACK || CurTok.Tok == TOK_LPAREN) { + if (CurTok.Tok == TOK_LPAREN) { /* Function declaration */ FuncDesc* F; NextToken (); @@ -855,7 +856,7 @@ static void Decl (Declaration* D, unsigned Mode) unsigned long Size = 0; NextToken (); /* Read the size if it is given */ - if (curtok != TOK_RBRACK) { + if (CurTok.Tok != TOK_RBRACK) { struct expent lval; constexpr (&lval); Size = lval.e_const; @@ -995,12 +996,12 @@ static void ParseVoidInit (void) } - if (curtok != TOK_COMMA) { + if (CurTok.Tok != TOK_COMMA) { break; } NextToken (); - } while (curtok != TOK_RCURLY); + } while (CurTok.Tok != TOK_RCURLY); ConsumeRCurly (); } @@ -1031,14 +1032,14 @@ static void ParseStructInit (type* Type) /* Get a pointer to the list of symbols */ Entry = Tab->SymHead; - while (curtok != TOK_RCURLY) { + while (CurTok.Tok != TOK_RCURLY) { if (Entry == 0) { Error ("Too many initializers"); return; } ParseInit (Entry->Type); Entry = Entry->NextSym; - if (curtok != TOK_COMMA) + if (CurTok.Tok != TOK_COMMA) break; NextToken (); } @@ -1105,20 +1106,20 @@ void ParseInit (type* T) case T_ARRAY: Size = Decode (T + 1); t = T + DECODE_SIZE + 1; - if (IsTypeChar(t) && curtok == TOK_SCONST) { - str = GetLiteral (curval); + if (IsTypeChar(t) && CurTok.Tok == TOK_SCONST) { + str = GetLiteral (CurTok.IVal); Count = strlen (str) + 1; - TranslateLiteralPool (curval); /* Translate into target charset */ + TranslateLiteralPool (CurTok.IVal); /* Translate into target charset */ g_defbytes (str, Count); - ResetLiteralPoolOffs (curval); /* Remove string from pool */ + ResetLiteralPoolOffs (CurTok.IVal); /* Remove string from pool */ NextToken (); } else { ConsumeLCurly (); Count = 0; - while (curtok != TOK_RCURLY) { + while (CurTok.Tok != TOK_RCURLY) { ParseInit (T + DECODE_SIZE + 1); ++Count; - if (curtok != TOK_COMMA) + if (CurTok.Tok != TOK_COMMA) break; NextToken (); } diff --git a/src/cc65/error.c b/src/cc65/error.c index d6557c57c..b61312855 100644 --- a/src/cc65/error.c +++ b/src/cc65/error.c @@ -43,6 +43,7 @@ /* cc65 */ #include "global.h" #include "input.h" +#include "lineinfo.h" #include "scanner.h" #include "stmt.h" #include "error.h" @@ -87,7 +88,7 @@ void Warning (const char* Format, ...) { va_list ap; va_start (ap, Format); - IntWarning (GetCurrentFile(), curpos, Format, ap); + IntWarning (GetInputName (CurTok.LI), GetInputLine (CurTok.LI), Format, ap); va_end (ap); } @@ -125,7 +126,7 @@ void Error (const char* Format, ...) { va_list ap; va_start (ap, Format); - IntError (GetCurrentFile(), curpos, Format, ap); + IntError (GetInputName (CurTok.LI), GetInputLine (CurTok.LI), Format, ap); va_end (ap); } @@ -146,8 +147,18 @@ void Fatal (const char* Format, ...) /* Print a message about a fatal error and die */ { va_list ap; + + const char* FileName; + unsigned LineNum; + if (CurTok.LI) { + FileName = GetInputName (CurTok.LI); + LineNum = GetInputLine (CurTok.LI); + } else { + FileName = GetCurrentFile (); + LineNum = GetCurrentLine (); + } - fprintf (stderr, "%s(%u): Fatal: ", GetCurrentFile(), curpos); + fprintf (stderr, "%s(%u): Fatal: ", FileName, LineNum); va_start (ap, Format); vfprintf (stderr, Format, ap); @@ -165,8 +176,18 @@ void Internal (char* Format, ...) { va_list ap; + const char* FileName; + unsigned LineNum; + if (CurTok.LI) { + FileName = GetInputName (CurTok.LI); + LineNum = GetInputLine (CurTok.LI); + } else { + FileName = GetCurrentFile (); + LineNum = GetCurrentLine (); + } + fprintf (stderr, "%s(%u): Internal compiler error:\n", - GetCurrentFile(), curpos); + FileName, LineNum); va_start (ap, Format); vfprintf (stderr, Format, ap); @@ -190,3 +211,4 @@ void ErrorReport (void) + diff --git a/src/cc65/expr.c b/src/cc65/expr.c index b5441dfd6..1c51d0139 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -431,13 +431,12 @@ static int istypeexpr (void) { SymEntry* Entry; - return curtok == TOK_LPAREN && ( - (nxttok >= TOK_FIRSTTYPE && nxttok <= TOK_LASTTYPE) || - (nxttok == TOK_CONST) || - (nxttok == TOK_IDENT && - (Entry = FindSym (NextTok.Ident)) != 0 && - IsTypeDef (Entry)) - ); + return CurTok.Tok == TOK_LPAREN && ( + (NextTok.Tok >= TOK_FIRSTTYPE && NextTok.Tok <= TOK_LASTTYPE) || + (NextTok.Tok == TOK_CONST) || + (NextTok.Tok == TOK_IDENT && + (Entry = FindSym (NextTok.Ident)) != 0 && + IsTypeDef (Entry))); } @@ -563,7 +562,7 @@ static unsigned FunctionParamList (FuncDesc* Func) } /* Parse the actual parameter list */ - while (curtok != TOK_RPAREN) { + while (CurTok.Tok != TOK_RPAREN) { unsigned CFlags; unsigned Flags; @@ -656,7 +655,7 @@ static unsigned FunctionParamList (FuncDesc* Func) } /* Check for end of argument list */ - if (curtok != TOK_COMMA) { + if (CurTok.Tok != TOK_COMMA) { break; } NextToken (); @@ -745,14 +744,14 @@ void doasm (void) ConsumeLParen (); /* String literal */ - if (curtok != TOK_SCONST) { + if (CurTok.Tok != TOK_SCONST) { Error ("String literal expected"); } else { /* The string literal may consist of more than one line of assembler * code. Separate the single lines and output the code. */ - const char* S = GetLiteral (curval); + const char* S = GetLiteral (CurTok.IVal); while (*S) { /* Allow lines up to 256 bytes */ @@ -773,7 +772,7 @@ void doasm (void) * will fail if the next token is also a string token, but that's a * syntax error anyway, because we expect a right paren. */ - ResetLiteralPoolOffs (curval); + ResetLiteralPoolOffs (CurTok.IVal); } /* Skip the string token */ @@ -794,10 +793,10 @@ static int primary (struct expent* lval) lval->e_test = 0; /* Character and integer constants. */ - if (curtok == TOK_ICONST || curtok == TOK_CCONST) { + if (CurTok.Tok == TOK_ICONST || CurTok.Tok == TOK_CCONST) { lval->e_flags = E_MCONST | E_TCONST; - lval->e_tptr = curtype; - lval->e_const = curval; + lval->e_tptr = CurTok.Type; + lval->e_const = CurTok.IVal; NextToken (); return 0; } @@ -805,7 +804,7 @@ static int primary (struct expent* lval) /* Process parenthesized subexpression by calling the whole parser * recursively. */ - if (curtok == TOK_LPAREN) { + if (CurTok.Tok == TOK_LPAREN) { NextToken (); memset (lval, 0, sizeof (*lval)); /* Remove any attributes */ k = hie0 (lval); @@ -825,7 +824,7 @@ static int primary (struct expent* lval) } /* Identifier? */ - if (curtok == TOK_IDENT) { + if (CurTok.Tok == TOK_IDENT) { SymEntry* Sym; ident Ident; @@ -915,7 +914,7 @@ static int primary (struct expent* lval) NextToken (); /* IDENT is either an auto-declared function or an undefined variable. */ - if (curtok == TOK_LPAREN) { + if (CurTok.Tok == TOK_LPAREN) { /* Declare a function returning int. For that purpose, prepare a * function signature for a function having an empty param list * and returning int. @@ -942,16 +941,16 @@ static int primary (struct expent* lval) } /* String literal? */ - if (curtok == TOK_SCONST) { + if (CurTok.Tok == TOK_SCONST) { lval->e_flags = E_MCONST | E_TLIT; - lval->e_const = curval; - lval->e_tptr = GetCharArrayType (strlen (GetLiteral (curval))); + lval->e_const = CurTok.IVal; + lval->e_tptr = GetCharArrayType (strlen (GetLiteral (CurTok.IVal))); NextToken (); return 0; } /* ASM statement? */ - if (curtok == TOK_ASM) { + if (CurTok.Tok == TOK_ASM) { doasm (); lval->e_tptr = type_void; lval->e_flags = E_MEXPR; @@ -960,8 +959,8 @@ static int primary (struct expent* lval) } /* __AX__ and __EAX__ pseudo values? */ - if (curtok == TOK_AX || curtok == TOK_EAX) { - lval->e_tptr = (curtok == TOK_AX)? type_uint : type_ulong; + if (CurTok.Tok == TOK_AX || CurTok.Tok == TOK_EAX) { + lval->e_tptr = (CurTok.Tok == TOK_AX)? type_uint : type_ulong; lval->e_flags = E_MREG; lval->e_test &= ~E_CC; lval->e_const = 0; @@ -1220,7 +1219,7 @@ static int structref (int k, struct expent* lval) /* Skip the token and check for an identifier */ NextToken (); - if (curtok != TOK_IDENT) { + if (CurTok.Tok != TOK_IDENT) { Error ("Identifier expected"); lval->e_tptr = type_int; return 0; @@ -1264,19 +1263,19 @@ static int hie11 (struct expent *lval) k = primary (lval); - if (curtok < TOK_LBRACK || curtok > TOK_PTR_REF) { + if (CurTok.Tok < TOK_LBRACK || CurTok.Tok > TOK_PTR_REF) { /* Not for us */ return k; } while (1) { - if (curtok == TOK_LBRACK) { + if (CurTok.Tok == TOK_LBRACK) { /* Array reference */ k = arrayref (k, lval); - } else if (curtok == TOK_LPAREN) { + } else if (CurTok.Tok == TOK_LPAREN) { /* Function call. Skip the opening parenthesis */ NextToken (); @@ -1296,14 +1295,14 @@ static int hie11 (struct expent *lval) } k = 0; - } else if (curtok == TOK_DOT) { + } else if (CurTok.Tok == TOK_DOT) { if (!IsClassStruct (lval->e_tptr)) { Error ("Struct expected"); } k = structref (0, lval); - } else if (curtok == TOK_PTR_REF) { + } else if (CurTok.Tok == TOK_PTR_REF) { tptr = lval->e_tptr; if (tptr[0] != T_PTR || (tptr[1] & T_STRUCT) == 0) { @@ -1612,7 +1611,7 @@ static int hie10 (struct expent* lval) int k; type* t; - switch (curtok) { + switch (CurTok.Tok) { case TOK_INC: pre_incdec (lval, g_inc); @@ -1625,7 +1624,7 @@ static int hie10 (struct expent* lval) case TOK_PLUS: case TOK_MINUS: case TOK_COMP: - unaryop (curtok, lval); + unaryop (CurTok.Tok, lval); return 0; case TOK_BOOL_NOT: @@ -1702,7 +1701,7 @@ static int hie10 (struct expent* lval) } k = hie11 (lval); - switch (curtok) { + switch (CurTok.Tok) { case TOK_INC: post_incdec (lval, k, g_inc); return 0; @@ -1737,7 +1736,7 @@ static int hie_internal (GenDesc** ops, /* List of generators */ k = hienext (lval); *UsedGen = 0; - while ((Gen = FindGen (curtok, ops)) != 0) { + while ((Gen = FindGen (CurTok.Tok, ops)) != 0) { /* Tell the caller that we handled it's ops */ *UsedGen = 1; @@ -1748,7 +1747,7 @@ static int hie_internal (GenDesc** ops, /* List of generators */ } /* Remember the operator token, then skip it */ - tok = curtok; + tok = CurTok.Tok; NextToken (); /* Get the lhs on stack */ @@ -1845,10 +1844,10 @@ static int hie_compare (GenDesc** ops, /* List of generators */ k = hienext (lval); - while ((Gen = FindGen (curtok, ops)) != 0) { + while ((Gen = FindGen (CurTok.Tok, ops)) != 0) { /* Remember the operator token, then skip it */ - tok = curtok; + tok = CurTok.Tok; NextToken (); /* Get the lhs on stack */ @@ -2305,9 +2304,9 @@ static int hie8 (struct expent* lval) /* Process + and - binary operators. */ { int k = hie9 (lval); - while (curtok == TOK_PLUS || curtok == TOK_MINUS) { + while (CurTok.Tok == TOK_PLUS || CurTok.Tok == TOK_MINUS) { - if (curtok == TOK_PLUS) { + if (CurTok.Tok == TOK_PLUS) { parseadd (k, lval); } else { parsesub (k, lval); @@ -2401,7 +2400,7 @@ static int hieAnd (struct expent* lval, unsigned TrueLab, int* BoolOp) struct expent lval2; k = hie2 (lval); - if (curtok == TOK_BOOL_AND) { + if (CurTok.Tok == TOK_BOOL_AND) { /* Tell our caller that we're evaluating a boolean */ *BoolOp = 1; @@ -2421,7 +2420,7 @@ static int hieAnd (struct expent* lval, unsigned TrueLab, int* BoolOp) g_falsejump (CF_NONE, lab); /* Parse more boolean and's */ - while (curtok == TOK_BOOL_AND) { + while (CurTok.Tok == TOK_BOOL_AND) { /* Skip the && */ NextToken (); @@ -2434,7 +2433,7 @@ static int hieAnd (struct expent* lval, unsigned TrueLab, int* BoolOp) exprhs (CF_FORCECHAR, k, &lval2); /* Do short circuit evaluation */ - if (curtok == TOK_BOOL_AND) { + if (CurTok.Tok == TOK_BOOL_AND) { g_falsejump (CF_NONE, lab); } else { /* Last expression - will evaluate to true */ @@ -2472,7 +2471,7 @@ static int hieOr (struct expent *lval) k = hieAnd (lval, TrueLab, &BoolOp); /* Any boolean or's? */ - if (curtok == TOK_BOOL_OR) { + if (CurTok.Tok == TOK_BOOL_OR) { /* If the expr hasn't set condition codes, set the force-test flag */ if ((lval->e_test & E_CC) == 0) { @@ -2493,7 +2492,7 @@ static int hieOr (struct expent *lval) BoolOp = 1; /* while there's more expr */ - while (curtok == TOK_BOOL_OR) { + while (CurTok.Tok == TOK_BOOL_OR) { /* skip the || */ NextToken (); @@ -2512,7 +2511,7 @@ static int hieOr (struct expent *lval) */ #if 0 /* Seems this sometimes generates wrong code */ - if (curtok == TOK_BOOL_OR && !AndOp) { + if (CurTok.Tok == TOK_BOOL_OR && !AndOp) { g_truejump (CF_NONE, TrueLab); } #else @@ -2555,7 +2554,7 @@ static int hieQuest (struct expent *lval) k = hieOr (lval); - if (curtok == TOK_QUEST) { + if (CurTok.Tok == TOK_QUEST) { NextToken (); if ((lval->e_test & E_CC) == 0) { /* Condition codes not set, force a test */ @@ -2901,7 +2900,7 @@ int hie1 (struct expent* lval) int k; k = hieQuest (lval); - switch (curtok) { + switch (CurTok.Tok) { case TOK_RPAREN: case TOK_SEMI: @@ -2970,7 +2969,7 @@ int hie0 (struct expent *lval) int k; k = hie1 (lval); - while (curtok == TOK_COMMA) { + while (CurTok.Tok == TOK_COMMA) { NextToken (); k = hie1 (lval); } @@ -3140,7 +3139,7 @@ void test (unsigned label, int cond) * compiler itself is one big hack...): If a semicolon follows, we * don't have a statement and may omit the jump. */ - if (curtok != TOK_SEMI) { + if (CurTok.Tok != TOK_SEMI) { g_falsejump (CF_NONE, label); } } diff --git a/src/cc65/function.c b/src/cc65/function.c index 463c4f2c6..bcddf88d2 100644 --- a/src/cc65/function.c +++ b/src/cc65/function.c @@ -294,8 +294,8 @@ void NewFunc (SymEntry* Func) /* Now process statements in this block */ HadReturn = 0; - while (curtok != TOK_RCURLY) { - if (curtok != TOK_CEOF) { + while (CurTok.Tok != TOK_RCURLY) { + if (CurTok.Tok != TOK_CEOF) { HadReturn = Statement (); } else { break; diff --git a/src/cc65/goto.c b/src/cc65/goto.c index 404d42e73..fe3e1b8bd 100644 --- a/src/cc65/goto.c +++ b/src/cc65/goto.c @@ -54,7 +54,7 @@ void DoGoto (void) NextToken (); /* Label name must follow */ - if (curtok != TOK_IDENT) { + if (CurTok.Tok != TOK_IDENT) { Error ("Label name expected"); diff --git a/src/cc65/input.c b/src/cc65/input.c index e84919fe3..307d3557e 100644 --- a/src/cc65/input.c +++ b/src/cc65/input.c @@ -45,8 +45,8 @@ /* cc65 */ #include "asmcode.h" #include "error.h" -#include "global.h" #include "incpath.h" +#include "lineinfo.h" #include "input.h" @@ -69,20 +69,12 @@ char NextC = '\0'; /* Maximum count of nested includes */ #define MAX_INC_NESTING 16 -/* Struct that describes an input file */ -typedef struct IFile IFile; -struct IFile { - unsigned Index; /* File index */ - unsigned Usage; /* Usage counter */ - char Name[1]; /* Name of file (dynamically allocated) */ -}; - /* Struct that describes an active input file */ typedef struct AFile AFile; struct AFile { unsigned Line; /* Line number for this file */ FILE* F; /* Input file stream */ - const char* Name; /* Points to corresponding IFile name */ + IFile* Input; /* Points to corresponding IFile */ }; /* List of all input files */ @@ -137,7 +129,7 @@ static AFile* NewAFile (IFile* IF, FILE* F) /* Initialize the fields */ AF->Line = 0; AF->F = F; - AF->Name = IF->Name; + AF->Input = IF; /* Increment the usage counter of the corresponding IFile */ ++IF->Usage; @@ -378,16 +370,6 @@ int NextLine (void) --Len; } line [Len] = '\0'; - -#if 0 - /* ######### */ - /* Output the source line in the generated assembler file - * if requested. - */ - if (AddSource && line[Start] != '\0') { - AddCodeLine ("; %s", line+Start); - } -#endif /* Check if we have a line continuation character at the end. If not, * we're done. @@ -402,6 +384,9 @@ int NextLine (void) /* Got a line. Initialize the current and next characters. */ InitLine (line); + /* Create line information for this line */ + UpdateLineInfo (Input->Input, Input->Line, line); + /* Done */ return 1; } @@ -414,7 +399,7 @@ const char* GetCurrentFile (void) unsigned AFileCount = CollCount (&AFiles); if (AFileCount > 0) { const AFile* AF = (const AFile*) CollAt (&AFiles, AFileCount-1); - return AF->Name; + return AF->Input->Name; } else { /* No open file. Use the main file if we have one. */ unsigned IFileCount = CollCount (&IFiles); diff --git a/src/cc65/input.h b/src/cc65/input.h index 4524ac98b..873f05c01 100644 --- a/src/cc65/input.h +++ b/src/cc65/input.h @@ -38,6 +38,10 @@ +#include + + + /*****************************************************************************/ /* data */ /*****************************************************************************/ @@ -56,6 +60,14 @@ extern const char* lptr; /* ### Remove this */ extern char CurC; extern char NextC; +/* Struct that describes an input file */ +typedef struct IFile IFile; +struct IFile { + unsigned Index; /* File index */ + unsigned Usage; /* Usage counter */ + char Name[1]; /* Name of file (dynamically allocated) */ +}; + /*****************************************************************************/ diff --git a/src/cc65/lineinfo.c b/src/cc65/lineinfo.c new file mode 100644 index 000000000..fbf954134 --- /dev/null +++ b/src/cc65/lineinfo.c @@ -0,0 +1,159 @@ +/*****************************************************************************/ +/* */ +/* lineinfo.c */ +/* */ +/* Source file line info structure */ +/* */ +/* */ +/* */ +/* (C) 2001 Ullrich von Bassewitz */ +/* Wacholderweg 14 */ +/* D-70597 Stuttgart */ +/* EMail: uz@musoftware.de */ +/* */ +/* */ +/* 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. */ +/* */ +/*****************************************************************************/ + + + +#include + +/* common */ +#include "check.h" +#include "xmalloc.h" + +/* cc65 */ +#include "input.h" +#include "lineinfo.h" + + + +/*****************************************************************************/ +/* Data */ +/*****************************************************************************/ + + + +/* Global pointer to line information for the current line */ +static LineInfo* CurLineInfo = 0; + + + +/*****************************************************************************/ +/* Code */ +/*****************************************************************************/ + + + +static LineInfo* NewLineInfo (struct IFile* F, unsigned LineNum, const char* Line) +/* Create and return a new line info. Ref count will be 1. */ +{ + /* Calculate the length of the line */ + unsigned Len = strlen (Line); + + /* Allocate memory */ + LineInfo* LI = xmalloc (sizeof (LineInfo) + Len); + + /* Initialize the fields */ + LI->RefCount = 1; + LI->InputFile = F; + LI->LineNum = LineNum; + memcpy (LI->Line, Line, Len+1); + + /* Return the new struct */ + return LI; +} + + + +static void FreeLineInfo (LineInfo* LI) +/* Free a LineInfo structure */ +{ + xfree (LI); +} + + + +LineInfo* UseLineInfo (LineInfo* LI) +/* Increase the reference count of the given line info and return it. */ +{ + CHECK (LI != 0); + ++LI->RefCount; + return LI; +} + + + +void ReleaseLineInfo (LineInfo* LI) +/* Release a reference to the given line info, free the structure if the + * reference count drops to zero. + */ +{ + CHECK (LI && LI->RefCount > 0); + if (--LI->RefCount == 0) { + /* No more references, free it */ + FreeLineInfo (LI); + } +} + + + +LineInfo* GetCurLineInfo (void) +/* Return a pointer to the current line info. The reference count is NOT + * increased, use UseLineInfo for that purpose. + */ +{ + return CurLineInfo; +} + + + +void UpdateLineInfo (struct IFile* F, unsigned LineNum, const char* Line) +/* Update the line info - called if a new line is read */ +{ + /* If a current line info exists, release it */ + if (CurLineInfo) { + ReleaseLineInfo (CurLineInfo); + } + + /* Create a new line info */ + CurLineInfo = NewLineInfo (F, LineNum, Line); +} + + + +const char* GetInputName (const LineInfo* LI) +/* Return the file name from a line info */ +{ + PRECONDITION (LI != 0); + return LI->InputFile->Name; +} + + + +unsigned GetInputLine (const LineInfo* LI) +/* Return the line number from a line info */ +{ + PRECONDITION (LI != 0); + return LI->LineNum; +} + + + diff --git a/src/cc65/lineinfo.h b/src/cc65/lineinfo.h new file mode 100644 index 000000000..3a19ca0ae --- /dev/null +++ b/src/cc65/lineinfo.h @@ -0,0 +1,106 @@ +/*****************************************************************************/ +/* */ +/* lineinfo.h */ +/* */ +/* Source file line info structure */ +/* */ +/* */ +/* */ +/* (C) 2001 Ullrich von Bassewitz */ +/* Wacholderweg 14 */ +/* D-70597 Stuttgart */ +/* EMail: uz@musoftware.de */ +/* */ +/* */ +/* 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 LINEINFO_H +#define LINEINFO_H + + + +/*****************************************************************************/ +/* Forwards */ +/*****************************************************************************/ + + + +/* Input file structure */ +struct IFile; + + + +/*****************************************************************************/ +/* Data */ +/*****************************************************************************/ + + + +/* The text for the actual line is allocated at the end of the structure, so + * the size of the structure varies. + */ +typedef struct LineInfo LineInfo; +struct LineInfo { + unsigned RefCount; /* Reference counter */ + struct IFile* InputFile; /* Input file for this line */ + unsigned LineNum; /* Line number */ + char Line[1]; /* Source code line */ +}; + + + +/*****************************************************************************/ +/* Code */ +/*****************************************************************************/ + + + +LineInfo* UseLineInfo (LineInfo* LI); +/* Increase the reference count of the given line info and return it. */ + +void ReleaseLineInfo (LineInfo* LI); +/* Release a reference to the given line info, free the structure if the + * reference count drops to zero. + */ + +LineInfo* GetCurLineInfo (void); +/* Return a pointer to the current line info. The reference count is NOT + * increased, use UseLineInfo for that purpose. + */ + +void UpdateLineInfo (struct IFile* F, unsigned LineNum, const char* Line); +/* Update the line info - called if a new line is read */ + +const char* GetInputName (const LineInfo* LI); +/* Return the file name from a line info */ + +unsigned GetInputLine (const LineInfo* LI); +/* Return the line number from a line info */ + + + +/* End of lineinfo.h */ +#endif + + + + diff --git a/src/cc65/locals.c b/src/cc65/locals.c index 888972707..414e72342 100644 --- a/src/cc65/locals.c +++ b/src/cc65/locals.c @@ -178,7 +178,7 @@ static void ParseOneDecl (const DeclSpec* Spec) /* Change SC in case it was register */ SC = (SC & ~SC_REGISTER) | SC_AUTO; - if (curtok == TOK_ASSIGN) { + if (CurTok.Tok == TOK_ASSIGN) { struct expent lval; @@ -233,7 +233,7 @@ static void ParseOneDecl (const DeclSpec* Spec) g_res (Size); /* Allow assignments */ - if (curtok == TOK_ASSIGN) { + if (CurTok.Tok == TOK_ASSIGN) { struct expent lval; @@ -263,7 +263,7 @@ static void ParseOneDecl (const DeclSpec* Spec) } else if ((SC & SC_STATIC) == SC_STATIC) { /* Static data */ - if (curtok == TOK_ASSIGN) { + if (CurTok.Tok == TOK_ASSIGN) { /* Initialization ahead, switch to data segment */ if (IsQualConst (Decl.Type)) { @@ -335,7 +335,7 @@ void DeclareLocals (void) } /* Accept type only declarations */ - if (curtok == TOK_SEMI) { + if (CurTok.Tok == TOK_SEMI) { /* Type declaration only */ CheckEmptyDecl (&Spec); NextToken (); @@ -349,7 +349,7 @@ void DeclareLocals (void) ParseOneDecl (&Spec); /* Check if there is more */ - if (curtok == TOK_COMMA) { + if (CurTok.Tok == TOK_COMMA) { /* More to come */ NextToken (); } else { diff --git a/src/cc65/make/gcc.mak b/src/cc65/make/gcc.mak index 1f34b4c28..ff780220c 100644 --- a/src/cc65/make/gcc.mak +++ b/src/cc65/make/gcc.mak @@ -49,6 +49,7 @@ OBJS = anonname.o \ ident.o \ incpath.o \ input.o \ + lineinfo.o \ litpool.o \ locals.o \ loop.o \ diff --git a/src/cc65/pragma.c b/src/cc65/pragma.c index ba3815d96..2bc155032 100644 --- a/src/cc65/pragma.c +++ b/src/cc65/pragma.c @@ -119,17 +119,17 @@ static pragma_t FindPragma (const char* Key) static void StringPragma (void (*Func) (const char*)) /* Handle a pragma that expects a string parameter */ { - if (curtok != TOK_SCONST) { + if (CurTok.Tok != TOK_SCONST) { Error ("String literal expected"); } else { /* Get the string */ - const char* Name = GetLiteral (curval); + const char* Name = GetLiteral (CurTok.IVal); /* Call the given function with the string argument */ Func (Name); /* Reset the string pointer, removing the string from the pool */ - ResetLiteralPoolOffs (curval); + ResetLiteralPoolOffs (CurTok.IVal); } /* Skip the string (or error) token */ @@ -141,11 +141,11 @@ static void StringPragma (void (*Func) (const char*)) static void SegNamePragma (segment_t Seg) /* Handle a pragma that expects a segment name parameter */ { - if (curtok != TOK_SCONST) { + if (CurTok.Tok != TOK_SCONST) { Error ("String literal expected"); } else { /* Get the segment name */ - const char* Name = GetLiteral (curval); + const char* Name = GetLiteral (CurTok.IVal); /* Check if the name is valid */ if (ValidSegName (Name)) { @@ -161,7 +161,7 @@ static void SegNamePragma (segment_t Seg) } /* Reset the string pointer, removing the string from the pool */ - ResetLiteralPoolOffs (curval); + ResetLiteralPoolOffs (CurTok.IVal); } /* Skip the string (or error) token */ @@ -192,7 +192,7 @@ void DoPragma (void) NextToken (); /* Identifier must follow */ - if (curtok != TOK_IDENT) { + if (CurTok.Tok != TOK_IDENT) { Error ("Identifier expected"); return; } diff --git a/src/cc65/scanner.c b/src/cc65/scanner.c index 598d5d214..27b300ceb 100644 --- a/src/cc65/scanner.c +++ b/src/cc65/scanner.c @@ -1,8 +1,35 @@ -/* - * scanner.c - * - * Ullrich von Bassewitz, 07.06.1998 - */ +/*****************************************************************************/ +/* */ +/* scanner.c */ +/* */ +/* Source file line info structure */ +/* */ +/* */ +/* */ +/* (C) 1998-2001 Ullrich von Bassewitz */ +/* Wacholderweg 14 */ +/* D-70597 Stuttgart */ +/* EMail: uz@musoftware.de */ +/* */ +/* */ +/* 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. */ +/* */ +/*****************************************************************************/ @@ -190,7 +217,7 @@ int IsSym (char *s) -static void unknown (char C) +static void UnknownChar (char C) /* Error message for unknown character */ { Error ("Invalid input character with code %02X", C & 0xFF); @@ -215,9 +242,9 @@ static unsigned hexval (int c) static void SetTok (int tok) -/* set nxttok and bump line ptr */ +/* Set NextTok.Tok and bump line ptr */ { - nxttok = tok; + NextTok.Tok = tok; NextChar (); } @@ -284,7 +311,7 @@ static int ParseChar (void) i = 0; C = CurC - '0'; while (NextC >= '0' && NextC <= '7' && i++ < 4) { - NextChar (); + NextChar (); C = (C << 3) | (CurC - '0'); } break; @@ -326,13 +353,13 @@ static void CharConst (void) } /* Setup values and attributes */ - nxttok = TOK_CCONST; + NextTok.Tok = TOK_CCONST; /* Translate into target charset */ - nxtval = SignExtendChar (TgtTranslateChar (C)); + NextTok.IVal = SignExtendChar (TgtTranslateChar (C)); /* Character constants have type int */ - nxttype = type_int; + NextTok.Type = type_int; } @@ -340,8 +367,8 @@ static void CharConst (void) static void StringConst (void) /* Parse a quoted string */ { - nxtval = GetLiteralPoolOffs (); - nxttok = TOK_SCONST; + NextTok.IVal = GetLiteralPoolOffs (); + NextTok.Tok = TOK_SCONST; /* Be sure to concatenate strings */ while (CurC == '\"') { @@ -376,16 +403,26 @@ void NextToken (void) { ident token; + /* We have to skip white space here before shifting tokens, since the + * tokens and the current line info is invalid at startup and will get + * initialized by reading the first time from the file. Remember if + * we were at end of input and handle that later. + */ + int GotEOF = (SkipWhite() == 0); + /* Current token is the lookahead token */ + if (CurTok.LI) { + ReleaseLineInfo (CurTok.LI); + } CurTok = NextTok; /* Remember the starting position of the next token */ - NextTok.Pos = GetCurrentLine(); + NextTok.LI = UseLineInfo (GetCurLineInfo ()); - /* Skip spaces and read the next line if needed */ - if (SkipWhite () == 0) { + /* Now handle end of input. */ + if (GotEOF) { /* End of file reached */ - nxttok = TOK_CEOF; + NextTok.Tok = TOK_CEOF; return; } @@ -409,7 +446,7 @@ void NextToken (void) NextChar (); if (toupper (CurC) == 'X') { base = 16; - nxttype = type_uint; + NextTok.Type = type_uint; NextChar (); /* gobble "x" */ } else { base = 8; @@ -473,25 +510,25 @@ void NextToken (void) /* Now set the type string to the smallest type in types */ if (types & IT_INT) { - nxttype = type_int; + NextTok.Type = type_int; } else if (types & IT_UINT) { - nxttype = type_uint; + NextTok.Type = type_uint; } else if (types & IT_LONG) { - nxttype = type_long; + NextTok.Type = type_long; } else { - nxttype = type_ulong; + NextTok.Type = type_ulong; } /* Set the value and the token */ - nxtval = k; - nxttok = TOK_ICONST; + NextTok.IVal = k; + NextTok.Tok = TOK_ICONST; return; } if (IsSym (token)) { /* Check for a keyword */ - if ((nxttok = FindKey (token)) != TOK_IDENT) { + if ((NextTok.Tok = FindKey (token)) != TOK_IDENT) { /* Reserved word found */ return; } @@ -499,19 +536,19 @@ void NextToken (void) if (token [0] == '_') { /* Special symbols */ if (strcmp (token, "__FILE__") == 0) { - nxtval = AddLiteral (GetCurrentFile()); - nxttok = TOK_SCONST; + NextTok.IVal = AddLiteral (GetCurrentFile()); + NextTok.Tok = TOK_SCONST; return; } else if (strcmp (token, "__LINE__") == 0) { - nxttok = TOK_ICONST; - nxtval = GetCurrentLine(); - nxttype = type_int; + NextTok.Tok = TOK_ICONST; + NextTok.IVal = GetCurrentLine(); + NextTok.Type = type_int; return; } else if (strcmp (token, "__func__") == 0) { /* __func__ is only defined in functions */ if (CurrentFunc) { - nxtval = AddLiteral (GetFuncName (CurrentFunc)); - nxttok = TOK_SCONST; + NextTok.IVal = AddLiteral (GetFuncName (CurrentFunc)); + NextTok.Tok = TOK_SCONST; return; } } @@ -531,7 +568,7 @@ void NextToken (void) if (CurC == '=') { SetTok (TOK_NE); } else { - nxttok = TOK_BOOL_NOT; + NextTok.Tok = TOK_BOOL_NOT; } break; @@ -544,7 +581,7 @@ void NextToken (void) if (CurC == '=') { SetTok (TOK_MOD_ASSIGN); } else { - nxttok = TOK_MOD; + NextTok.Tok = TOK_MOD; } break; @@ -558,7 +595,7 @@ void NextToken (void) SetTok (TOK_AND_ASSIGN); break; default: - nxttok = TOK_AND; + NextTok.Tok = TOK_AND; } break; @@ -579,7 +616,7 @@ void NextToken (void) if (CurC == '=') { SetTok (TOK_MUL_ASSIGN); } else { - nxttok = TOK_STAR; + NextTok.Tok = TOK_STAR; } break; @@ -593,7 +630,7 @@ void NextToken (void) SetTok (TOK_PLUS_ASSIGN); break; default: - nxttok = TOK_PLUS; + NextTok.Tok = TOK_PLUS; } break; @@ -614,7 +651,7 @@ void NextToken (void) SetTok (TOK_PTR_REF); break; default: - nxttok = TOK_MINUS; + NextTok.Tok = TOK_MINUS; } break; @@ -625,10 +662,10 @@ void NextToken (void) if (CurC == '.') { SetTok (TOK_ELLIPSIS); } else { - unknown (CurC); + UnknownChar (CurC); } } else { - nxttok = TOK_DOT; + NextTok.Tok = TOK_DOT; } break; @@ -637,7 +674,7 @@ void NextToken (void) if (CurC == '=') { SetTok (TOK_DIV_ASSIGN); } else { - nxttok = TOK_DIV; + NextTok.Tok = TOK_DIV; } break; @@ -660,11 +697,11 @@ void NextToken (void) if (CurC == '=') { SetTok (TOK_SHL_ASSIGN); } else { - nxttok = TOK_SHL; + NextTok.Tok = TOK_SHL; } break; default: - nxttok = TOK_LT; + NextTok.Tok = TOK_LT; } break; @@ -673,7 +710,7 @@ void NextToken (void) if (CurC == '=') { SetTok (TOK_EQ); } else { - nxttok = TOK_ASSIGN; + NextTok.Tok = TOK_ASSIGN; } break; @@ -688,11 +725,11 @@ void NextToken (void) if (CurC == '=') { SetTok (TOK_SHR_ASSIGN); } else { - nxttok = TOK_SHR; + NextTok.Tok = TOK_SHR; } break; default: - nxttok = TOK_GT; + NextTok.Tok = TOK_GT; } break; @@ -713,7 +750,7 @@ void NextToken (void) if (CurC == '=') { SetTok (TOK_XOR_ASSIGN); } else { - nxttok = TOK_XOR; + NextTok.Tok = TOK_XOR; } break; @@ -731,7 +768,7 @@ void NextToken (void) SetTok (TOK_OR_ASSIGN); break; default: - nxttok = TOK_OR; + NextTok.Tok = TOK_OR; } break; @@ -752,11 +789,11 @@ void NextToken (void) /* OOPS - should not happen */ Error ("Preprocessor directive expected"); } - nxttok = TOK_PRAGMA; + NextTok.Tok = TOK_PRAGMA; break; default: - unknown (CurC); + UnknownChar (CurC); } @@ -769,7 +806,7 @@ void Consume (token_t Token, const char* ErrorMsg) * message. */ { - if (curtok == Token) { + if (CurTok.Tok == Token) { NextToken (); } else { Error (ErrorMsg); @@ -790,11 +827,11 @@ void ConsumeSemi (void) /* Check for a semicolon and skip it. */ { /* Try do be smart about typos... */ - if (curtok == TOK_SEMI) { + if (CurTok.Tok == TOK_SEMI) { NextToken (); } else { Error ("`;' expected"); - if (curtok == TOK_COLON || curtok == TOK_COMMA) { + if (CurTok.Tok == TOK_COLON || CurTok.Tok == TOK_COMMA) { NextToken (); } } diff --git a/src/cc65/scanner.h b/src/cc65/scanner.h index af424af97..97614b62e 100644 --- a/src/cc65/scanner.h +++ b/src/cc65/scanner.h @@ -1,8 +1,35 @@ -/* - * scanner.h - * - * Ullrich von Bassewitz, 07.06.1998 - */ +/*****************************************************************************/ +/* */ +/* scanner.h */ +/* */ +/* Source file line info structure */ +/* */ +/* */ +/* */ +/* (C) 1998-2001 Ullrich von Bassewitz */ +/* Wacholderweg 14 */ +/* D-70597 Stuttgart */ +/* EMail: uz@musoftware.de */ +/* */ +/* */ +/* 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. */ +/* */ +/*****************************************************************************/ @@ -11,8 +38,10 @@ +/* cc65 */ #include "datatype.h" #include "ident.h" +#include "lineinfo.h" @@ -146,30 +175,19 @@ typedef enum token_t { /* Token stuff */ -typedef struct Token_ Token; -struct Token_ { - token_t Tok; /* The token itself */ - long IVal; /* The integer attribute */ - double FVal; /* The float attribute */ - ident Ident; /* Identifier if IDENT */ - unsigned Pos; /* Source line where the token comes from */ +typedef struct Token Token; +struct Token { + token_t Tok; /* The token itself */ + long IVal; /* The integer attribute */ + double FVal; /* The float attribute */ + ident Ident; /* Identifier if IDENT */ + LineInfo* LI; /* Source line where the token comes from */ type* Type; /* Type if integer or float constant */ }; extern Token CurTok; /* The current token */ extern Token NextTok; /* The next token */ -/* Defines to make the old code work */ -#define curtok CurTok.Tok -#define curval CurTok.IVal -#define curpos CurTok.Pos -#define curtype CurTok.Type - -#define nxttok NextTok.Tok -#define nxtval NextTok.IVal -#define nxtpos NextTok.Pos -#define nxttype NextTok.Type - /*****************************************************************************/ diff --git a/src/cc65/segments.c b/src/cc65/segments.c index 2c6f3e3cd..37e193801 100644 --- a/src/cc65/segments.c +++ b/src/cc65/segments.c @@ -40,6 +40,7 @@ #include "chartype.h" #include "check.h" #include "coll.h" +#include "scanner.h" #include "xmalloc.h" /* cc65 */ @@ -210,7 +211,7 @@ void AddCodeLine (const char* Format, ...) va_list ap; va_start (ap, Format); CHECK (CS != 0); - AddCodeEntry (CS->Code, Format, ap); + AddCodeEntry (CS->Code, CurTok.LI, Format, ap); va_end (ap); } diff --git a/src/cc65/stmt.c b/src/cc65/stmt.c index 2e1c05b98..7260dd1f7 100644 --- a/src/cc65/stmt.c +++ b/src/cc65/stmt.c @@ -69,7 +69,7 @@ static int doif (void) gotbreak = Statement (); /* Else clause present? */ - if (curtok != TOK_ELSE) { + if (CurTok.Tok != TOK_ELSE) { g_defcodelabel (flab1); /* Since there's no else clause, we're not sure, if the a break @@ -130,7 +130,7 @@ static void dowhile (char wtype) * do another small optimization here, and use a conditional jump * instead an absolute one. */ - if (curtok == TOK_SEMI) { + if (CurTok.Tok == TOK_SEMI) { /* Shortcut */ NextToken (); /* Use a conditional jump */ @@ -163,7 +163,7 @@ static void DoReturn (void) struct expent lval; NextToken (); - if (curtok != TOK_SEMI) { + if (CurTok.Tok != TOK_SEMI) { if (HasVoidReturn (CurrentFunc)) { Error ("Returning a value in function with return type void"); } @@ -280,9 +280,9 @@ static void cascadeswitch (struct expent* eval) /* Parse the labels */ lcount = 0; - while (curtok != TOK_RCURLY) { + while (CurTok.Tok != TOK_RCURLY) { - if (curtok == TOK_CASE || curtok == TOK_DEFAULT) { + 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. @@ -301,10 +301,10 @@ static void cascadeswitch (struct expent* eval) NextLab = 0; } - while (curtok == TOK_CASE || curtok == TOK_DEFAULT) { + while (CurTok.Tok == TOK_CASE || CurTok.Tok == TOK_DEFAULT) { /* Parse the selector */ - if (curtok == TOK_CASE) { + if (CurTok.Tok == TOK_CASE) { /* Count labels */ ++lcount; @@ -325,25 +325,25 @@ static void cascadeswitch (struct expent* eval) case T_SCHAR: /* Signed char */ if (Val < -128 || Val > 127) { - Error ("Range error"); + Error ("Range error"); } break; case T_UCHAR: if (Val < 0 || Val > 255) { - Error ("Range error"); + Error ("Range error"); } break; case T_INT: if (Val < -32768 || Val > 32767) { - Error ("Range error"); + Error ("Range error"); } break; case T_UINT: if (Val < 0 || Val > 65535) { - Error ("Range error"); + Error ("Range error"); } break; @@ -351,22 +351,19 @@ static void cascadeswitch (struct expent* eval) Internal ("Invalid type: %02X", *eval->e_tptr & 0xFF); } - /* Skip the colon */ - ConsumeColon (); - /* Emit a compare */ g_cmp (Flags, Val); /* If another case follows, we will jump to the code if * the condition is true. */ - if (curtok == TOK_CASE) { + if (CurTok.Tok == TOK_CASE) { /* Create a code label if needed */ if (CodeLab == 0) { CodeLab = GetLocalLabel (); } g_falsejump (CF_NONE, CodeLab); - } else if (curtok != TOK_DEFAULT) { + } else if (CurTok.Tok != TOK_DEFAULT) { /* No case follows, jump to next selector */ if (NextLab == 0) { NextLab = GetLocalLabel (); @@ -374,22 +371,25 @@ static void cascadeswitch (struct expent* eval) g_truejump (CF_NONE, NextLab); } + /* Skip the colon */ + ConsumeColon (); + } else { /* Default case */ NextToken (); - /* Skip the colon */ - ConsumeColon (); - /* Handle the pathologic case: DEFAULT followed by CASE */ - if (curtok == TOK_CASE) { + if (CurTok.Tok == TOK_CASE) { if (CodeLab == 0) { CodeLab = GetLocalLabel (); } g_jump (CodeLab); } + /* Skip the colon */ + ConsumeColon (); + /* Remember that we had a default label */ HaveDefault = 1; } @@ -405,7 +405,7 @@ static void cascadeswitch (struct expent* eval) } /* Parse statements */ - if (curtok != TOK_RCURLY) { + if (CurTok.Tok != TOK_RCURLY) { HaveBreak = Statement (); } } @@ -415,9 +415,6 @@ static void cascadeswitch (struct expent* eval) Warning ("No case labels"); } - /* Eat the closing curly brace */ - NextToken (); - /* Define the exit label and, if there's a next label left, create this * one, too. */ @@ -426,6 +423,9 @@ static void cascadeswitch (struct expent* eval) } g_defcodelabel (ExitLab); + /* Eat the closing curly brace */ + NextToken (); + /* End the loop */ DelLoop (); } @@ -467,14 +467,14 @@ static void tableswitch (struct expent* eval) /* Jump behind the code for the CASE labels */ g_jump (lcase = GetLocalLabel ()); lcount = 0; - while (curtok != TOK_RCURLY) { - if (curtok == TOK_CASE || curtok == TOK_DEFAULT) { + 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_CASE) { + if (CurTok.Tok == TOK_CASE) { NextToken (); constexpr (&lval); if (!IsClassInt (lval.e_tptr)) { @@ -490,11 +490,11 @@ static void tableswitch (struct expent* eval) HaveDefault = 1; } ConsumeColon (); - } while (curtok == TOK_CASE || curtok == TOK_DEFAULT); + } while (CurTok.Tok == TOK_CASE || CurTok.Tok == TOK_DEFAULT); g_defcodelabel (label); HaveBreak = 0; } - if (curtok != TOK_RCURLY) { + if (CurTok.Tok != TOK_RCURLY) { HaveBreak = Statement (); } } @@ -586,12 +586,12 @@ static void dofor (void) lstat = GetLocalLabel (); AddLoop (oursp, loop, lab, linc, lstat); ConsumeLParen (); - if (curtok != TOK_SEMI) { /* exp1 */ + if (CurTok.Tok != TOK_SEMI) { /* exp1 */ expression (&lval1); } ConsumeSemi (); g_defcodelabel (loop); - if (curtok != TOK_SEMI) { /* exp2 */ + if (CurTok.Tok != TOK_SEMI) { /* exp2 */ boolexpr (&lval2); g_truejump (CF_NONE, lstat); g_jump (lab); @@ -600,7 +600,7 @@ static void dofor (void) } ConsumeSemi (); g_defcodelabel (linc); - if (curtok != TOK_RPAREN) { /* exp3 */ + if (CurTok.Tok != TOK_RPAREN) { /* exp3 */ expression (&lval3); } ConsumeRParen (); @@ -634,8 +634,8 @@ static int CompoundStatement (void) /* Now process statements in this block */ isbrk = 0; - while (curtok != TOK_RCURLY) { - if (curtok != TOK_CEOF) { + while (CurTok.Tok != TOK_RCURLY) { + if (CurTok.Tok != TOK_CEOF) { isbrk = Statement (); } else { break; @@ -672,14 +672,14 @@ int Statement (void) struct expent lval; /* */ - if (curtok == TOK_IDENT && nxttok == TOK_COLON) { + if (CurTok.Tok == TOK_IDENT && NextTok.Tok == TOK_COLON) { /* Special handling for a label */ DoLabel (); } else { - switch (curtok) { + switch (CurTok.Tok) { case TOK_LCURLY: return CompoundStatement (); -- 2.39.5