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:
parent
3d1e244a8a
commit
4555fdcad1
@ -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)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -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 ();
|
||||
|
@ -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");
|
||||
|
956
src/ca65/expr.c
956
src/ca65/expr.c
File diff suppressed because it is too large
Load Diff
@ -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.
|
||||
|
@ -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 */
|
||||
|
@ -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);
|
||||
|
@ -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 '>':
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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 */
|
||||
|
||||
|
@ -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)
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -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 */
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user