1
0
mirror of https://github.com/cc65/cc65.git synced 2024-06-09 06:29:38 +00:00

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
This commit is contained in:
cuz 2001-05-22 09:32:24 +00:00
parent caf73cf15f
commit 0e80187cec
23 changed files with 693 additions and 357 deletions

View File

@ -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)

View File

@ -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);

View File

@ -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));

View File

@ -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 */

View File

@ -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 */

View File

@ -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 ();

View File

@ -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 */

View File

@ -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 ();
}

View File

@ -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)

View File

@ -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);
}
}

View File

@ -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;

View File

@ -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");

View File

@ -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);

View File

@ -38,6 +38,10 @@
#include <stdio.h>
/*****************************************************************************/
/* 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) */
};
/*****************************************************************************/

159
src/cc65/lineinfo.c Normal file
View File

@ -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 <string.h>
/* 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;
}

106
src/cc65/lineinfo.h Normal file
View File

@ -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

View File

@ -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 {

View File

@ -49,6 +49,7 @@ OBJS = anonname.o \
ident.o \
incpath.o \
input.o \
lineinfo.o \
litpool.o \
locals.o \
loop.o \

View File

@ -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;
}

View File

@ -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 ();
}
}

View File

@ -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
/*****************************************************************************/

View File

@ -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);
}

View File

@ -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 ();