mirror of
https://github.com/cc65/cc65.git
synced 2025-01-11 11:30:13 +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:
parent
caf73cf15f
commit
0e80187cec
@ -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)
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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));
|
||||
|
||||
|
@ -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 */
|
||||
|
@ -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 */
|
||||
|
||||
|
@ -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 ();
|
||||
|
@ -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 */
|
||||
|
@ -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 ();
|
||||
}
|
||||
|
@ -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)
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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");
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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
159
src/cc65/lineinfo.c
Normal 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
106
src/cc65/lineinfo.h
Normal 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
|
||||
|
||||
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -49,6 +49,7 @@ OBJS = anonname.o \
|
||||
ident.o \
|
||||
incpath.o \
|
||||
input.o \
|
||||
lineinfo.o \
|
||||
litpool.o \
|
||||
locals.o \
|
||||
loop.o \
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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 ();
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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 ();
|
||||
|
Loading…
x
Reference in New Issue
Block a user