1
0
mirror of https://github.com/cc65/cc65.git synced 2024-12-23 04:30:10 +00:00

Rewrote expression evaluation. More smaller changes.

git-svn-id: svn://svn.cc65.org/cc65/trunk@2638 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
cuz 2003-11-11 13:57:30 +00:00
parent 3d1e244a8a
commit 4555fdcad1
14 changed files with 668 additions and 637 deletions

View File

@ -7,7 +7,7 @@
/* */
/* */
/* (C) 2003 Ullrich von Bassewitz */
/* Römerstrasse 52 */
/* Römerstraße 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
/* */
@ -118,9 +118,6 @@ void WriteAssertions (void)
/* Get the next assertion */
Assertion* A = CollAtUnchecked (&Assertions, I);
/* Finalize the expression */
A->Expr = FinalizeExpr (A->Expr);
/* Write it to the file */
WriteExpr (A->Expr);
ObjWriteVar (A->Action);
@ -134,4 +131,4 @@ void WriteAssertions (void)

View File

@ -295,7 +295,7 @@ void DoConditionals (void)
NextTok ();
if (IfCond) {
ExprNode* Expr = Expression();
SetIfCond (D, IsConstExpr (Expr));
SetIfCond (D, IsConstExpr (Expr, 0));
FreeExpr (Expr);
}
IfCond = GetCurrentIfCond ();
@ -330,7 +330,7 @@ void DoConditionals (void)
NextTok ();
if (IfCond) {
ExprNode* Expr = Expression();
SetIfCond (D, !IsConstExpr (Expr));
SetIfCond (D, !IsConstExpr (Expr, 0));
FreeExpr (Expr);
}
IfCond = GetCurrentIfCond ();

View File

@ -181,8 +181,8 @@ void Internal (const char* Format, ...)
/* Print a message about an internal compiler error and die. */
{
va_list ap;
va_start (ap, Format);
fprintf (stderr, "Internal assembler error\n");
va_start (ap, Format);
fprintf (stderr, "Internal assembler error:\n");
vfprintf (stderr, Format, ap);
va_end (ap);
fprintf (stderr, "\n");

File diff suppressed because it is too large Load Diff

View File

@ -7,7 +7,7 @@
/* */
/* */
/* (C) 1998-2003 Ullrich von Bassewitz */
/* Römerstrasse 52 */
/* Römerstraße 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
/* */
@ -92,30 +92,21 @@ ExprNode* GenWordExpr (ExprNode* Expr);
ExprNode* GenNE (ExprNode* Expr, long Val);
/* Generate an expression that compares Expr and Val for inequality */
int IsConstExpr (ExprNode* Root);
int IsConstExpr (ExprNode* Expr, long* Val);
/* Return true if the given expression is a constant expression, that is, one
* with no references to external symbols.
* with no references to external symbols. If Val is not NULL and the
* expression is constant, the constant value is stored here.
*/
int IsByteExpr (ExprNode* Root);
/* Return true if this is a byte expression */
long GetExprVal (ExprNode* Expr);
/* Get the value of a constant expression */
int IsByteRange (long Val);
/* Return true if this is a byte value */
int IsWordRange (long Val);
/* Return true if this is a word value */
ExprNode* FinalizeExpr (ExprNode* Expr);
/* Resolve any symbols by cloning the symbol expression tree instead of the
* symbol reference, then try to simplify the expression as much as possible.
* This function must only be called if all symbols are resolved (no undefined
* symbol errors).
*/
ExprNode* CloneExpr (ExprNode* Expr);
/* Clone the given expression tree. The function will simply clone symbol
* nodes, it will not resolve them.

View File

@ -673,8 +673,8 @@ static long PutImmed8 (const InsDesc* Ins)
}
/* If we have an expression and it's const, get it's value */
if (A.Expr && IsConstExpr (A.Expr)) {
Val = GetExprVal (A.Expr);
if (A.Expr) {
(void) IsConstExpr (A.Expr, &Val);
}
/* Check how many extension bytes are needed and output the instruction */

View File

@ -144,10 +144,10 @@ void EmitData (const unsigned char* Data, unsigned Size)
void EmitByte (ExprNode* Expr)
/* Emit one byte */
{
if (IsConstExpr (Expr)) {
{
long Val;
if (IsConstExpr (Expr, &Val)) {
/* Constant expression, emit literal byte */
long Val = GetExprVal (Expr);
FreeExpr (Expr);
if ((Val & ~0xFF) != 0) {
Error ("Range error");
@ -167,9 +167,9 @@ void EmitByte (ExprNode* Expr)
void EmitWord (ExprNode* Expr)
/* Emit one word */
{
if (IsConstExpr (Expr)) {
long Val;
if (IsConstExpr (Expr, &Val)) {
/* Constant expression, emit literal byte */
long Val = GetExprVal (Expr);
FreeExpr (Expr);
if ((Val & ~0xFFFF) != 0) {
Error ("Range error");
@ -190,9 +190,9 @@ void EmitWord (ExprNode* Expr)
void EmitFarAddr (ExprNode* Expr)
/* Emit a 24 bit expression */
{
if (IsConstExpr (Expr)) {
long Val;
if (IsConstExpr (Expr, &Val)) {
/* Constant expression, emit literal byte */
long Val = GetExprVal (Expr);
FreeExpr (Expr);
if ((Val & ~0xFFFFFF) != 0) {
Error ("Range error");
@ -214,9 +214,9 @@ void EmitFarAddr (ExprNode* Expr)
void EmitDWord (ExprNode* Expr)
/* Emit one dword */
{
if (IsConstExpr (Expr)) {
long Val;
if (IsConstExpr (Expr, &Val)) {
/* Constant expression, emit literal byte */
long Val = GetExprVal (Expr);
FreeExpr (Expr);
Emit0 (Val & 0xFF);
Emit0 ((Val >> 8) & 0xFF);

View File

@ -122,7 +122,7 @@ struct DotKeyword {
{ ".A8", TOK_A8 },
{ ".ADDR", TOK_ADDR },
{ ".ALIGN", TOK_ALIGN },
{ ".AND", TOK_BAND },
{ ".AND", TOK_BOOLAND },
{ ".ASCIIZ", TOK_ASCIIZ },
{ ".ASSERT", TOK_ASSERT },
{ ".AUTOIMPORT", TOK_AUTOIMPORT },
@ -206,9 +206,9 @@ struct DotKeyword {
{ ".MATCH", TOK_MATCH },
{ ".MID", TOK_MID },
{ ".MOD", TOK_MOD },
{ ".NOT", TOK_BNOT },
{ ".NOT", TOK_BOOLNOT },
{ ".NULL", TOK_NULL },
{ ".OR", TOK_BOR },
{ ".OR", TOK_BOOLOR },
{ ".ORG", TOK_ORG },
{ ".OUT", TOK_OUT },
{ ".P02", TOK_P02 },
@ -247,7 +247,7 @@ struct DotKeyword {
{ ".WARNING", TOK_WARNING },
{ ".WORD", TOK_WORD },
{ ".XMATCH", TOK_XMATCH },
{ ".XOR", TOK_BXOR },
{ ".XOR", TOK_BOOLXOR },
{ ".ZEROPAGE", TOK_ZEROPAGE },
};
@ -875,7 +875,7 @@ CharAgain:
NextChar ();
if (C == '&') {
NextChar ();
Tok = TOK_BAND;
Tok = TOK_BOOLAND;
} else {
Tok = TOK_AND;
}
@ -885,7 +885,7 @@ CharAgain:
NextChar ();
if (C == '|') {
NextChar ();
Tok = TOK_BOR;
Tok = TOK_BOOLOR;
} else {
Tok = TOK_OR;
}
@ -989,7 +989,7 @@ CharAgain:
case '!':
NextChar ();
Tok = TOK_BNOT;
Tok = TOK_BOOLNOT;
return;
case '>':

View File

@ -77,10 +77,10 @@ enum Token {
TOK_LE, /* <= */
TOK_GE, /* >= */
TOK_BAND, /* .and */
TOK_BOR, /* .or */
TOK_BXOR, /* .xor */
TOK_BNOT, /* .not */
TOK_BOOLAND, /* .and */
TOK_BOOLOR, /* .or */
TOK_BOOLXOR, /* .xor */
TOK_BOOLNOT, /* .not */
TOK_PLUS, /* + */
TOK_MINUS, /* - */
@ -90,6 +90,7 @@ enum Token {
TOK_MOD, /* ! */
TOK_OR, /* | */
TOK_XOR, /* ^ */
TOK_BANK = TOK_XOR, /* Alias */
TOK_AND, /* & */
TOK_SHL, /* << */
TOK_SHR, /* >> */
@ -192,7 +193,7 @@ enum Token {
TOK_MID,
TOK_NULL,
TOK_ORG,
TOK_OUT,
TOK_OUT,
TOK_P02,
TOK_P816,
TOK_PAGELENGTH,

View File

@ -290,13 +290,12 @@ void SegCheck (void)
Fragment* F = S->Root;
while (F) {
if (F->Type == FRAG_EXPR || F->Type == FRAG_SEXPR) {
F->V.Expr = FinalizeExpr (F->V.Expr);
if (IsConstExpr (F->V.Expr)) {
/* We are able to evaluate the expression. Get the value
* and check for range errors.
long Val;
if (IsConstExpr (F->V.Expr, &Val)) {
/* We are able to evaluate the expression. Check for
* range errors.
*/
unsigned I;
long Val = GetExprVal (F->V.Expr);
int Abs = (F->Type != FRAG_SEXPR);
if (F->Len == 1) {
@ -317,36 +316,36 @@ void SegCheck (void)
if (Val > 65535) {
PError (&F->Pos, "Range error");
}
} else {
/* PC relative value */
if (Val < -32768 || Val > 32767) {
PError (&F->Pos, "Range error");
}
}
}
} else {
/* PC relative value */
if (Val < -32768 || Val > 32767) {
PError (&F->Pos, "Range error");
}
}
}
/* We don't need the expression tree any longer */
FreeExpr (F->V.Expr);
/* Convert the fragment into a literal fragment */
for (I = 0; I < F->Len; ++I) {
F->V.Data [I] = Val & 0xFF;
Val >>= 8;
/* Convert the fragment into a literal fragment */
for (I = 0; I < F->Len; ++I) {
F->V.Data [I] = Val & 0xFF;
Val >>= 8;
}
F->Type = FRAG_LITERAL;
} else {
/* We cannot evaluate the expression now, leave the job for
* the linker. However, we are able to check for explicit
* byte expressions and we will do so.
*/
if (F->Type == FRAG_EXPR && F->Len == 1 && !IsByteExpr (F->V.Expr)) {
PError (&F->Pos, "Range error");
}
}
}
F = F->Next;
}
S = S->List;
F->Type = FRAG_LITERAL;
} else {
/* We cannot evaluate the expression now, leave the job for
* the linker. However, we are able to check for explicit
* byte expressions and we will do so.
*/
if (F->Type == FRAG_EXPR && F->Len == 1 && !IsByteExpr (F->V.Expr)) {
PError (&F->Pos, "Range error");
}
}
}
F = F->Next;
}
S = S->List;
}
}
@ -378,7 +377,7 @@ void SegDump (void)
} else if (F->Type == FRAG_EXPR || F->Type == FRAG_SEXPR) {
State = 1;
printf ("\n Expression (%u): ", F->Len);
DumpExpr (F->V.Expr);
DumpExpr (F->V.Expr, SymResolve);
} else if (F->Type == FRAG_FILL) {
State = 1;
printf ("\n Fill bytes (%u)", F->Len);

View File

@ -7,7 +7,7 @@
/* */
/* */
/* (C) 1998-2003 Ullrich von Bassewitz */
/* Römerstrasse 52 */
/* Römerstraße 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
/* */
@ -160,15 +160,7 @@ void SymDef (SymEntry* S, ExprNode* Expr, unsigned AddrSize, unsigned Flags)
}
/* Set the symbol value */
if (IsConstExpr (Expr)) {
/* Expression is const, store the value */
S->Flags |= SF_CONST;
S->V.Val = GetExprVal (Expr);
FreeExpr (Expr);
} else {
/* Not const, store the expression */
S->V.Expr = Expr;
}
S->V.Expr = Expr;
/* If the symbol is marked as global, export it */
if (S->Flags & SF_GLOBAL) {
@ -182,7 +174,10 @@ void SymDef (SymEntry* S, ExprNode* Expr, unsigned AddrSize, unsigned Flags)
/* If the symbol is exported, check the address sizes */
if (S->Flags & SF_EXPORT) {
if (S->AddrSize > S->ExportSize) {
if (S->ExportSize == ADDR_SIZE_DEFAULT) {
/* Use the real size of the symbol */
S->ExportSize = S->AddrSize;
} else if (S->AddrSize > S->ExportSize) {
Warning (1, "Address size mismatch for symbol `%s'", GetSymName (S));
}
}
@ -262,11 +257,6 @@ void SymExport (SymEntry* S, unsigned AddrSize, unsigned Flags)
return;
}
/* Map a default address size to a real value */
if (AddrSize == ADDR_SIZE_DEFAULT) {
AddrSize = SymAddrSize (S);
}
/* If the symbol was already marked as an export or global, check if
* this was done specifiying the same address size. In case of a global
* declaration, silently remove the global flag.
@ -283,7 +273,10 @@ void SymExport (SymEntry* S, unsigned AddrSize, unsigned Flags)
* exported size.
*/
if (S->Flags & SF_DEFINED) {
if (S->AddrSize > S->ExportSize) {
if (S->ExportSize == ADDR_SIZE_DEFAULT) {
/* Use the real size of the symbol */
S->ExportSize = S->AddrSize;
} else if (S->AddrSize > S->ExportSize) {
Warning (1, "Address size mismatch for symbol `%s'", GetSymName (S));
}
}
@ -374,6 +367,22 @@ int SymIsImport (const SymEntry* S)
int SymIsConst (SymEntry* S, long* Val)
/* Return true if the given symbol has a constant value. If Val is not NULL
* and the symbol has a constant value, store it's value there.
*/
{
/* Resolve trampoline entries */
if (S->Flags & SF_TRAMPOLINE) {
S = S->V.Sym;
}
/* Check for constness */
return (SymHasExpr (S) && IsConstExpr (S->V.Expr, Val));
}
int SymHasExpr (const SymEntry* S)
/* Return true if the given symbol has an associated expression */
{
@ -383,26 +392,7 @@ int SymHasExpr (const SymEntry* S)
}
/* Check the expression */
return ((S->Flags & SF_DEFINED) != 0 &&
(S->Flags & SF_IMPORT) == 0 &&
(S->Flags & SF_CONST) == 0);
}
void SymFinalize (SymEntry* S)
/* Finalize a symbol expression if there is one */
{
/* Resolve trampoline entries */
if (S->Flags & SF_TRAMPOLINE) {
S = S->V.Sym;
}
/* Check if we have an expression */
if ((S->Flags & SF_FINALIZED) == 0 && SymHasExpr (S)) {
S->V.Expr = FinalizeExpr (S->V.Expr);
S->Flags |= SF_FINALIZED;
}
return ((S->Flags & (SF_DEFINED|SF_IMPORT)) == SF_DEFINED);
}
@ -449,20 +439,6 @@ int SymHasUserMark (SymEntry* S)
long GetSymVal (SymEntry* S)
/* Return the symbol value */
{
/* Resolve trampoline entries */
if (S->Flags & SF_TRAMPOLINE) {
S = S->V.Sym;
}
PRECONDITION ((S->Flags & SF_DEFINED) != 0 && (S->Flags & SF_CONST) != 0);
return S->V.Val;
}
struct ExprNode* GetSymExpr (SymEntry* S)
/* Get the expression for a non-const symbol */
{
@ -471,12 +447,27 @@ struct ExprNode* GetSymExpr (SymEntry* S)
S = S->V.Sym;
}
PRECONDITION (S != 0 && (S->Flags & SF_CONST) == 0);
PRECONDITION (S != 0 && SymHasExpr (S));
return S->V.Expr;
}
const struct ExprNode* SymResolve (const SymEntry* S)
/* Helper function for DumpExpr. Resolves a symbol into an expression or return
* NULL. Do not call in other contexts!
*/
{
/* Resolve trampoline entries */
if (S->Flags & SF_TRAMPOLINE) {
S = S->V.Sym;
}
return SymHasExpr (S)? S->V.Expr : 0;
}
const char* GetSymName (SymEntry* S)
/* Return the name of the symbol */
{
@ -496,7 +487,7 @@ unsigned GetSymIndex (SymEntry* S)
if (S->Flags & SF_TRAMPOLINE) {
S = S->V.Sym;
}
PRECONDITION (S != 0 && (S->Flags & SF_INDEXED));
PRECONDITION (S != 0 && (S->Flags & SF_INDEXED) != 0);
return S->Index;
}

View File

@ -7,7 +7,7 @@
/* */
/* */
/* (C) 1998-2003 Ullrich von Bassewitz */
/* Römerstrasse 52 */
/* Römerstraße 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
/* */
@ -60,9 +60,7 @@
#define SF_GLOBAL 0x0010 /* Global symbol */
#define SF_LABEL 0x0080 /* Used as a label */
#define SF_FORCED 0x0100 /* Forced import, SF_IMPORT also set */
#define SF_FINALIZED 0x0200 /* Symbol is finalized */
#define SF_INDEXED 0x0800 /* Index is valid */
#define SF_CONST 0x1000 /* The symbol has a constant value */
#define SF_MULTDEF 0x2000 /* Multiply defined symbol */
#define SF_DEFINED 0x4000 /* Defined */
#define SF_REFERENCED 0x8000 /* Referenced */
@ -164,12 +162,14 @@ int SymIsRef (const SymEntry* Sym);
int SymIsImport (const SymEntry* Sym);
/* Return true if the given symbol is marked as import */
int SymIsConst (SymEntry* Sym, long* Val);
/* Return true if the given symbol has a constant value. If Val is not NULL
* and the symbol has a constant value, store it's value there.
*/
int SymHasExpr (const SymEntry* Sym);
/* Return true if the given symbol has an associated expression */
void SymFinalize (SymEntry* S);
/* Finalize a symbol expression if there is one */
void SymMarkUser (SymEntry* Sym);
/* Set a user mark on the specified symbol */
@ -179,12 +179,14 @@ void SymUnmarkUser (SymEntry* Sym);
int SymHasUserMark (SymEntry* Sym);
/* Return the state of the user mark for the specified symbol */
long GetSymVal (SymEntry* Sym);
/* Return the symbol value */
struct ExprNode* GetSymExpr (SymEntry* Sym);
/* Get the expression for a non-const symbol */
const struct ExprNode* SymResolve (const SymEntry* Sym);
/* Helper function for DumpExpr. Resolves a symbol into an expression or return
* NULL. Do not call in other contexts!
*/
const char* GetSymName (SymEntry* Sym);
/* Return the name of the symbol */

View File

@ -434,30 +434,6 @@ void SymConDes (const char* Name, unsigned Type, unsigned Prio)
int SymIsConst (SymEntry* S)
/* Return true if the given symbol has a constant value */
{
/* Resolve trampoline entries */
if (S->Flags & SF_TRAMPOLINE) {
S = S->V.Sym;
}
/* Check for constness */
if (S->Flags & SF_CONST) {
return 1;
} else if ((S->Flags & SF_DEFINED) && IsConstExpr (S->V.Expr)) {
/* Constant expression, remember the value */
ExprNode* Expr = S->V.Expr;
S->Flags |= SF_CONST;
S->V.Val = GetExprVal (Expr);
FreeExpr (Expr);
return 1;
}
return 0;
}
int SymIsZP (SymEntry* S)
/* Return true if the symbol is explicitly marked as zeropage symbol */
{
@ -705,26 +681,6 @@ void WriteImports (void)
static unsigned char GetExportExprMask (SymEntry* S)
/* Return the expression bits for the given symbol table entry */
{
unsigned char ExprMask;
/* Check if the symbol is const */
ExprMask = (SymIsConst (S))? EXP_CONST : EXP_EXPR;
/* Add zeropage/abs bits */
ExprMask |= (S->ExportSize == ADDR_SIZE_ZP)? EXP_ZP : EXP_ABS;
/* Add the label/equate bits */
ExprMask |= (S->Flags & SF_LABEL)? EXP_LABEL : EXP_EQUATE;
/* Return the mask */
return ExprMask;
}
void WriteExports (void)
/* Write the exports list to the object file */
{
@ -741,13 +697,13 @@ void WriteExports (void)
S = SymList;
while (S) {
if ((S->Flags & SF_EXPMASK) == SF_EXPVAL) {
unsigned char ExprMask;
/* Finalize an associated expression if we have one */
SymFinalize (S);
long ConstVal;
/* Get the expression bits */
ExprMask = GetExportExprMask (S);
unsigned char ExprMask = SymIsConst (S, &ConstVal)? EXP_CONST : EXP_EXPR;
ExprMask |= (S->ExportSize == ADDR_SIZE_ZP)? EXP_ZP : EXP_ABS;
ExprMask |= (S->Flags & SF_LABEL)? EXP_LABEL : EXP_EQUATE;
/* Count the number of ConDes types */
for (Type = 0; Type < CD_TYPE_COUNT; ++Type) {
@ -775,7 +731,7 @@ void WriteExports (void)
/* Write the value */
if ((ExprMask & EXP_MASK_VAL) == EXP_CONST) {
/* Constant value */
ObjWrite32 (S->V.Val);
ObjWrite32 (ConstVal);
} else {
/* Expression involved */
WriteExpr (S->V.Expr);
@ -793,26 +749,6 @@ void WriteExports (void)
static unsigned char GetDbgExprMask (SymEntry* S)
/* Return the expression bits for the given symbol table entry */
{
unsigned char ExprMask;
/* Check if the symbol is const */
ExprMask = (SymIsConst (S))? EXP_CONST : EXP_EXPR;
/* Add zeropage/abs bits */
ExprMask |= (S->AddrSize == ADDR_SIZE_ZP)? EXP_ZP : EXP_ABS;
/* Add the label/equate bits */
ExprMask |= (S->Flags & SF_LABEL)? EXP_LABEL : EXP_EQUATE;
/* Return the mask */
return ExprMask;
}
void WriteDbgSyms (void)
/* Write a list of all symbols to the object file */
{
@ -842,13 +778,13 @@ void WriteDbgSyms (void)
S = SymList;
while (S) {
if ((S->Flags & SF_DBGINFOMASK) == SF_DBGINFOVAL) {
unsigned char ExprMask;
/* Finalize an associated expression if we have one */
SymFinalize (S);
long ConstVal;
/* Get the expression bits */
ExprMask = GetDbgExprMask (S);
unsigned char ExprMask = (SymIsConst (S, &ConstVal))? EXP_CONST : EXP_EXPR;
ExprMask |= (S->AddrSize == ADDR_SIZE_ZP)? EXP_ZP : EXP_ABS;
ExprMask |= (S->Flags & SF_LABEL)? EXP_LABEL : EXP_EQUATE;
/* Write the type */
ObjWrite8 (ExprMask);
@ -859,7 +795,7 @@ void WriteDbgSyms (void)
/* Write the value */
if ((ExprMask & EXP_MASK_VAL) == EXP_CONST) {
/* Constant value */
ObjWrite32 (S->V.Val);
ObjWrite32 (ConstVal);
} else {
/* Expression involved */
WriteExpr (S->V.Expr);
@ -885,3 +821,4 @@ void WriteDbgSyms (void)

View File

@ -7,7 +7,7 @@
/* */
/* */
/* (C) 1998-2003 Ullrich von Bassewitz */
/* Römerstrasse 52 */
/* Römerstraße 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
/* */
@ -54,7 +54,7 @@
/* Symbol table flags */
/* Symbol table flags */
#define ST_NONE 0x00 /* No flags */
#define ST_DEFINED 0x01 /* Scope has been defined */
@ -107,9 +107,6 @@ void SymConDes (const char* Name, unsigned Type, unsigned Prio);
* mark the symbol as an export. Initializers may never be zero page symbols.
*/
int SymIsConst (SymEntry* Sym);
/* Return true if the given symbol has a constant value */
int SymIsZP (SymEntry* Sym);
/* Return true if the symbol is explicitly marked as zeropage symbol */