1
0
mirror of https://github.com/cc65/cc65.git synced 2024-06-30 16:29:58 +00:00

Work on named scopes

git-svn-id: svn://svn.cc65.org/cc65/trunk@2592 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
cuz 2003-10-31 20:21:48 +00:00
parent 8abe61a32f
commit fbdbf4d07c
12 changed files with 503 additions and 278 deletions

83
src/ca65/anonname.c Normal file
View File

@ -0,0 +1,83 @@
/*****************************************************************************/
/* */
/* anonname.c */
/* */
/* Create names for anonymous scopes/variables/types */
/* */
/* */
/* */
/* (C) 2000-2003 Ullrich von Bassewitz */
/* Römerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
/* */
/* */
/* 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 <stdio.h>
#include <string.h>
/* common */
#include "xsprintf.h"
/* ca65 */
#include "anonname.h"
/*****************************************************************************/
/* Data */
/*****************************************************************************/
static const char AnonTag[] = "$anon";
/*****************************************************************************/
/* Code */
/*****************************************************************************/
char* AnonName (char* Buf, unsigned Size, const char* Spec)
/* Get a name for an anonymous scope, variable or type. Size is the size of
* the buffer passed to the function, Spec will be used as part of the
* identifier if given. A pointer to the buffer is returned.
*/
{
static unsigned ACount = 0;
xsprintf (Buf, Size, "%s-%s-%04X", AnonTag, Spec, ++ACount);
return Buf;
}
int IsAnonName (const char* Name)
/* Check if the given symbol name is that of an anonymous symbol */
{
return (strncmp (Name, AnonTag, sizeof (AnonTag) - 1) == 0);
}

62
src/ca65/anonname.h Normal file
View File

@ -0,0 +1,62 @@
/*****************************************************************************/
/* */
/* anonname.h */
/* */
/* Create names for anonymous scopes/variables/types */
/* */
/* */
/* */
/* (C) 2000-2003 Ullrich von Bassewitz */
/* Römerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
/* */
/* */
/* 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 ANONNAME_H
#define ANONNAME_H
/*****************************************************************************/
/* Code */
/*****************************************************************************/
char* AnonName (char* Buf, unsigned Size, const char* Spec);
/* Get a name for an anonymous scope, variable or type. Size is the size of
* the buffer passed to the function, Spec will be used as part of the
* identifier if given. A pointer to the buffer is returned.
*/
int IsAnonName (const char* Name);
/* Check if the given symbol name is that of an anonymous symbol */
/* End of anonname.h */
#endif

View File

@ -84,7 +84,7 @@ static unsigned FreeNodeCount = 0;
static ExprNode* NewExprNode (void) static ExprNode* NewExprNode (unsigned Op)
/* Create a new expression node */ /* Create a new expression node */
{ {
ExprNode* N; ExprNode* N;
@ -98,7 +98,7 @@ static ExprNode* NewExprNode (void)
/* Allocate fresh memory */ /* Allocate fresh memory */
N = xmalloc (sizeof (ExprNode)); N = xmalloc (sizeof (ExprNode));
} }
N->Op = EXPR_NULL; N->Op = Op;
N->Left = N->Right = 0; N->Left = N->Right = 0;
N->Obj = 0; N->Obj = 0;
@ -560,9 +560,7 @@ static ExprNode* Factor (void)
N = GenLiteralExpr (GetSymVal (S)); N = GenLiteralExpr (GetSymVal (S));
} else { } else {
/* Create symbol node */ /* Create symbol node */
N = NewExprNode (); N = GenSymExpr (S);
N->Op = EXPR_SYMBOL;
N->V.Sym = S;
} }
NextTok (); NextTok ();
} }
@ -575,9 +573,7 @@ static ExprNode* Factor (void)
N = GenLiteralExpr (GetSymVal (S)); N = GenLiteralExpr (GetSymVal (S));
} else { } else {
/* Create symbol node */ /* Create symbol node */
N = NewExprNode (); N = GenSymExpr (S);
N->Op = EXPR_SYMBOL;
N->V.Sym = S;
} }
NextTok (); NextTok ();
break; break;
@ -589,16 +585,14 @@ static ExprNode* Factor (void)
case TOK_MINUS: case TOK_MINUS:
NextTok (); NextTok ();
N = NewExprNode (); N = NewExprNode (EXPR_UNARY_MINUS);
N->Left = Factor (); N->Left = Factor ();
N->Op = EXPR_UNARY_MINUS;
break; break;
case TOK_NOT: case TOK_NOT:
NextTok (); NextTok ();
N = NewExprNode (); N = NewExprNode (EXPR_NOT);
N->Left = Factor (); N->Left = Factor ();
N->Op = EXPR_NOT;
break; break;
case TOK_STAR: case TOK_STAR:
@ -609,16 +603,14 @@ static ExprNode* Factor (void)
case TOK_LT: case TOK_LT:
NextTok (); NextTok ();
N = NewExprNode (); N = NewExprNode (EXPR_BYTE0);
N->Left = Factor (); N->Left = Factor ();
N->Op = EXPR_BYTE0;
break; break;
case TOK_GT: case TOK_GT:
NextTok (); NextTok ();
N = NewExprNode (); N = NewExprNode (EXPR_BYTE1);
N->Left = Factor (); N->Left = Factor ();
N->Op = EXPR_BYTE1;
break; break;
case TOK_LPAREN: case TOK_LPAREN:
@ -697,32 +689,29 @@ static ExprNode* Factor (void)
static ExprNode* Term (void) static ExprNode* Term (void)
{ {
ExprNode* Root;
/* Read left hand side */ /* Read left hand side */
Root = Factor (); ExprNode* Root = Factor ();
/* Handle multiplicative operations */ /* Handle multiplicative operations */
while (Tok == TOK_MUL || Tok == TOK_DIV || Tok == TOK_MOD || while (Tok == TOK_MUL || Tok == TOK_DIV || Tok == TOK_MOD ||
Tok == TOK_AND || Tok == TOK_XOR || Tok == TOK_SHL || Tok == TOK_AND || Tok == TOK_XOR || Tok == TOK_SHL ||
Tok == TOK_SHR) { Tok == TOK_SHR) {
/* Create a new node and insert the left expression */ /* Create the new node */
ExprNode* Left = Root; ExprNode* Left = Root;
Root = NewExprNode ();
Root->Left = Left;
/* Determine the operator token */
switch (Tok) { switch (Tok) {
case TOK_MUL: Root->Op = EXPR_MUL; break; case TOK_MUL: Root = NewExprNode (EXPR_MUL); break;
case TOK_DIV: Root->Op = EXPR_DIV; break; case TOK_DIV: Root = NewExprNode (EXPR_DIV); break;
case TOK_MOD: Root->Op = EXPR_MOD; break; case TOK_MOD: Root = NewExprNode (EXPR_MOD); break;
case TOK_AND: Root->Op = EXPR_AND; break; case TOK_AND: Root = NewExprNode (EXPR_AND); break;
case TOK_XOR: Root->Op = EXPR_XOR; break; case TOK_XOR: Root = NewExprNode (EXPR_XOR); break;
case TOK_SHL: Root->Op = EXPR_SHL; break; case TOK_SHL: Root = NewExprNode (EXPR_SHL); break;
case TOK_SHR: Root->Op = EXPR_SHR; break; case TOK_SHR: Root = NewExprNode (EXPR_SHR); break;
default: Internal ("Invalid token"); default: Internal ("Invalid token");
} }
Root->Left = Left;
/* Skip the operator token */
NextTok (); NextTok ();
/* Parse the right hand side */ /* Parse the right hand side */
@ -738,26 +727,23 @@ static ExprNode* Term (void)
static ExprNode* SimpleExpr (void) static ExprNode* SimpleExpr (void)
{ {
ExprNode* Root;
/* Read left hand side */ /* Read left hand side */
Root = Term (); ExprNode* Root = Term ();
/* Handle additive operations */ /* Handle additive operations */
while (Tok == TOK_PLUS || Tok == TOK_MINUS || Tok == TOK_OR) { while (Tok == TOK_PLUS || Tok == TOK_MINUS || Tok == TOK_OR) {
/* Create a new node and insert the left expression */ /* Create the new node */
ExprNode* Left = Root; ExprNode* Left = Root;
Root = NewExprNode ();
Root->Left = Left;
/* Determine the operator token */
switch (Tok) { switch (Tok) {
case TOK_PLUS: Root->Op = EXPR_PLUS; break; case TOK_PLUS: Root = NewExprNode (EXPR_PLUS); break;
case TOK_MINUS: Root->Op = EXPR_MINUS; break; case TOK_MINUS: Root = NewExprNode (EXPR_MINUS); break;
case TOK_OR: Root->Op = EXPR_OR; break; case TOK_OR: Root = NewExprNode (EXPR_OR); break;
default: Internal ("Invalid token"); default: Internal ("Invalid token");
} }
Root->Left = Left;
/* Skip the operator token */
NextTok (); NextTok ();
/* Parse the right hand side */ /* Parse the right hand side */
@ -781,21 +767,20 @@ static ExprNode* BoolExpr (void)
while (Tok == TOK_EQ || Tok == TOK_NE || Tok == TOK_LT || while (Tok == TOK_EQ || Tok == TOK_NE || Tok == TOK_LT ||
Tok == TOK_GT || Tok == TOK_LE || Tok == TOK_GE) { Tok == TOK_GT || Tok == TOK_LE || Tok == TOK_GE) {
/* Create a new node and insert the left expression */ /* Create the new node */
ExprNode* Left = Root; ExprNode* Left = Root;
Root = NewExprNode ();
Root->Left = Left;
/* Determine the operator token */
switch (Tok) { switch (Tok) {
case TOK_EQ: Root->Op = EXPR_EQ; break; case TOK_EQ: Root = NewExprNode (EXPR_EQ); break;
case TOK_NE: Root->Op = EXPR_NE; break; case TOK_NE: Root = NewExprNode (EXPR_NE); break;
case TOK_LT: Root->Op = EXPR_LT; break; case TOK_LT: Root = NewExprNode (EXPR_LT); break;
case TOK_GT: Root->Op = EXPR_GT; break; case TOK_GT: Root = NewExprNode (EXPR_GT); break;
case TOK_LE: Root->Op = EXPR_LE; break; case TOK_LE: Root = NewExprNode (EXPR_LE); break;
case TOK_GE: Root->Op = EXPR_GE; break; case TOK_GE: Root = NewExprNode (EXPR_GE); break;
default: Internal ("Invalid token"); default: Internal ("Invalid token");
} }
Root->Left = Left;
/* Skip the operator token */
NextTok (); NextTok ();
/* Parse the right hand side */ /* Parse the right hand side */
@ -818,17 +803,16 @@ static ExprNode* Expr2 (void)
/* Handle booleans */ /* Handle booleans */
while (Tok == TOK_BAND || Tok == TOK_BXOR) { while (Tok == TOK_BAND || Tok == TOK_BXOR) {
/* Create a new node and insert the left expression */ /* Create the new node */
ExprNode* Left = Root; ExprNode* Left = Root;
Root = NewExprNode ();
Root->Left = Left;
/* Determine the operator token */
switch (Tok) { switch (Tok) {
case TOK_BAND: Root->Op = EXPR_BAND; break; case TOK_BAND: Root = NewExprNode (EXPR_BAND); break;
case TOK_BXOR: Root->Op = EXPR_BXOR; break; case TOK_BXOR: Root = NewExprNode (EXPR_BXOR); break;
default: Internal ("Invalid token"); default: Internal ("Invalid token");
} }
Root->Left = Left;
/* Skip the operator token */
NextTok (); NextTok ();
/* Parse the right hand side */ /* Parse the right hand side */
@ -851,16 +835,15 @@ static ExprNode* Expr1 (void)
/* Handle booleans */ /* Handle booleans */
while (Tok == TOK_BOR) { while (Tok == TOK_BOR) {
/* Create a new node and insert the left expression */ /* Create the new node */
ExprNode* Left = Root; ExprNode* Left = Root;
Root = NewExprNode ();
Root->Left = Left;
/* Determine the operator token */
switch (Tok) { switch (Tok) {
case TOK_BOR: Root->Op = EXPR_BOR; break; case TOK_BOR: Root = NewExprNode (EXPR_BOR); break;
default: Internal ("Invalid token"); default: Internal ("Invalid token");
} }
Root->Left = Left;
/* Skip the operator token */
NextTok (); NextTok ();
/* Parse the right hand side */ /* Parse the right hand side */
@ -882,14 +865,10 @@ static ExprNode* Expr0 (void)
/* Handle booleans */ /* Handle booleans */
if (Tok == TOK_BNOT) { if (Tok == TOK_BNOT) {
/* Create a new node */ /* Create the new node */
Root = NewExprNode (); Root = NewExprNode (EXPR_BNOT);
/* Determine the operator token */ /* Skip the operator token */
switch (Tok) {
case TOK_BNOT: Root->Op = EXPR_BNOT; break;
default: Internal ("Invalid token");
}
NextTok (); NextTok ();
/* Parse the left hand side, allow more BNOTs */ /* Parse the left hand side, allow more BNOTs */
@ -912,8 +891,8 @@ static ExprNode* SimplifyExpr (ExprNode* Root)
/* Try to simplify the given expression tree */ /* Try to simplify the given expression tree */
{ {
if (Root) { if (Root) {
SimplifyExpr (Root->Left); Root->Left = SimplifyExpr (Root->Left);
SimplifyExpr (Root->Right); Root->Right = SimplifyExpr (Root->Right);
if (IsConstExpr (Root)) { if (IsConstExpr (Root)) {
/* The complete expression is constant */ /* The complete expression is constant */
Root->V.Val = GetExprVal (Root); Root->V.Val = GetExprVal (Root);
@ -966,6 +945,10 @@ void FreeExpr (ExprNode* Root)
if (Root) { if (Root) {
FreeExpr (Root->Left); FreeExpr (Root->Left);
FreeExpr (Root->Right); FreeExpr (Root->Right);
if (Root->Op == EXPR_SYMBOL) {
/* Remove the symbol reference */
SymDelRef (Root->V.Sym, Root);
}
FreeExprNode (Root); FreeExprNode (Root);
} }
} }
@ -975,30 +958,44 @@ void FreeExpr (ExprNode* Root)
ExprNode* GenLiteralExpr (long Val) ExprNode* GenLiteralExpr (long Val)
/* Return an expression tree that encodes the given literal value */ /* Return an expression tree that encodes the given literal value */
{ {
ExprNode* Expr = NewExprNode (); ExprNode* Expr = NewExprNode (EXPR_LITERAL);
Expr->Op = EXPR_LITERAL;
Expr->V.Val = Val; Expr->V.Val = Val;
return Expr; return Expr;
} }
ExprNode* GenSymExpr (SymEntry* Sym)
/* Return an expression node that encodes the given symbol */
{
ExprNode* Expr = NewExprNode (EXPR_SYMBOL);
Expr->V.Sym = Sym;
SymAddRef (Sym, Expr);
return Expr;
}
static ExprNode* GenSectionExpr (unsigned SegNum)
/* Return an expression node for the given section */
{
ExprNode* Expr = NewExprNode (EXPR_SECTION);
Expr->V.SegNum = SegNum;
return Expr;
}
ExprNode* GenCurrentPC (void) ExprNode* GenCurrentPC (void)
/* Return the current program counter as expression */ /* Return the current program counter as expression */
{ {
ExprNode* Left;
ExprNode* Root; ExprNode* Root;
if (RelocMode) { if (RelocMode) {
/* Create SegmentBase + Offset */ /* Create SegmentBase + Offset */
Left = NewExprNode (); Root = NewExprNode (EXPR_PLUS);
Left->Op = EXPR_SECTION; Root->Left = GenSectionExpr (GetSegNum ());
Left->V.SegNum = GetSegNum ();
Root = NewExprNode ();
Root->Left = Left;
Root->Right = GenLiteralExpr (GetPC ()); Root->Right = GenLiteralExpr (GetPC ());
Root->Op = EXPR_PLUS;
} else { } else {
/* Absolute mode, just return PC value */ /* Absolute mode, just return PC value */
Root = GenLiteralExpr (GetPC ()); Root = GenLiteralExpr (GetPC ());
@ -1012,8 +1009,7 @@ ExprNode* GenCurrentPC (void)
ExprNode* GenSwapExpr (ExprNode* Expr) ExprNode* GenSwapExpr (ExprNode* Expr)
/* Return an extended expression with lo and hi bytes swapped */ /* Return an extended expression with lo and hi bytes swapped */
{ {
ExprNode* N = NewExprNode (); ExprNode* N = NewExprNode (EXPR_SWAP);
N->Op = EXPR_SWAP;
N->Left = Expr; N->Left = Expr;
return N; return N;
} }
@ -1027,27 +1023,20 @@ ExprNode* GenBranchExpr (unsigned Offs)
{ {
ExprNode* N; ExprNode* N;
ExprNode* Root; ExprNode* Root;
ExprNode* Left;
/* Create *+Offs */ /* Create *+Offs */
if (RelocMode) { if (RelocMode) {
Left = NewExprNode (); N = NewExprNode (EXPR_PLUS);
Left->Op = EXPR_SECTION; N->Left = GenSectionExpr (GetSegNum ());
Left->V.SegNum = GetSegNum ();
N = NewExprNode ();
N->Left = Left;
N->Right = GenLiteralExpr (GetPC () + Offs); N->Right = GenLiteralExpr (GetPC () + Offs);
N->Op = EXPR_PLUS;
} else { } else {
N = GenLiteralExpr (GetPC () + Offs); N = GenLiteralExpr (GetPC () + Offs);
} }
/* Create the root node */ /* Create the root node */
Root = NewExprNode (); Root = NewExprNode (EXPR_MINUS);
Root->Left = Expression (); Root->Left = Expression ();
Root->Right = N; Root->Right = N;
Root->Op = EXPR_MINUS;
/* Return the result */ /* Return the result */
return SimplifyExpr (Root); return SimplifyExpr (Root);
@ -1058,11 +1047,7 @@ ExprNode* GenBranchExpr (unsigned Offs)
ExprNode* GenULabelExpr (unsigned Num) ExprNode* GenULabelExpr (unsigned Num)
/* Return an expression for an unnamed label with the given index */ /* Return an expression for an unnamed label with the given index */
{ {
/* Get an expression node */ ExprNode* Node = NewExprNode (EXPR_ULABEL);
ExprNode* Node = NewExprNode ();
/* Set the values */
Node->Op = EXPR_ULABEL;
Node->V.Val = Num; Node->V.Val = Num;
/* Return the new node */ /* Return the new node */
@ -1075,9 +1060,8 @@ ExprNode* GenByteExpr (ExprNode* Expr)
/* Force the given expression into a byte and return the result */ /* Force the given expression into a byte and return the result */
{ {
/* Use the low byte operator to force the expression into byte size */ /* Use the low byte operator to force the expression into byte size */
ExprNode* Root = NewExprNode (); ExprNode* Root = NewExprNode (EXPR_BYTE0);
Root->Left = Expr; Root->Left = Expr;
Root->Op = EXPR_BYTE0;
/* Return the result */ /* Return the result */
return Root; return Root;
@ -1089,9 +1073,8 @@ ExprNode* GenWordExpr (ExprNode* Expr)
/* Force the given expression into a word and return the result. */ /* Force the given expression into a word and return the result. */
{ {
/* AND the expression by $FFFF to force it into word size */ /* AND the expression by $FFFF to force it into word size */
ExprNode* Root = NewExprNode (); ExprNode* Root = NewExprNode (EXPR_AND);
Root->Left = Expr; Root->Left = Expr;
Root->Op = EXPR_AND;
Root->Right = GenLiteralExpr (0xFFFF); Root->Right = GenLiteralExpr (0xFFFF);
/* Return the result */ /* Return the result */
@ -1104,9 +1087,8 @@ ExprNode* GenNE (ExprNode* Expr, long Val)
/* Generate an expression that compares Expr and Val for inequality */ /* Generate an expression that compares Expr and Val for inequality */
{ {
/* Generate a compare node */ /* Generate a compare node */
ExprNode* Root = NewExprNode (); ExprNode* Root = NewExprNode (EXPR_NE);
Root->Left = Expr; Root->Left = Expr;
Root->Op = EXPR_NE;
Root->Right = GenLiteralExpr (Val); Root->Right = GenLiteralExpr (Val);
/* Return the result */ /* Return the result */
@ -1165,7 +1147,7 @@ int IsConstExpr (ExprNode* Root)
} else { } else {
return IsConstExpr (Root->Right); return IsConstExpr (Root->Right);
} }
} else { } else {
/* lhs not const --> tree not const */ /* lhs not const --> tree not const */
return 0; return 0;
} }
@ -1208,7 +1190,7 @@ static void CheckByteExpr (const ExprNode* N, int* IsByte)
case EXPR_SYMBOL: case EXPR_SYMBOL:
if (SymIsZP (N->V.Sym)) { if (SymIsZP (N->V.Sym)) {
*IsByte = 1; *IsByte = 1;
} else if (SymHasExpr (N->V.Sym)) { } else if (SymHasExpr (N->V.Sym)) {
/* Check if this expression is a byte expression */ /* Check if this expression is a byte expression */
*IsByte = IsByteExpr (GetSymExpr (N->V.Sym)); *IsByte = IsByteExpr (GetSymExpr (N->V.Sym));
} }
@ -1403,31 +1385,31 @@ static ExprNode* RemoveSyms (ExprNode* Expr, int MustClone)
case EXPR_SYMBOL: case EXPR_SYMBOL:
if (SymHasExpr (Expr->V.Sym)) { if (SymHasExpr (Expr->V.Sym)) {
/* The symbol has an expression tree */ /* The symbol has an expression tree */
SymEntry* Sym = Expr->V.Sym; SymEntry* Sym = Expr->V.Sym;
if (SymHasUserMark (Sym)) { if (SymHasUserMark (Sym)) {
/* Circular definition */ /* Circular definition */
if (Verbosity) { if (Verbosity) {
DumpExpr (Expr); DumpExpr (Expr);
} }
PError (GetSymPos (Sym), ERR_CIRCULAR_REFERENCE); PError (GetSymPos (Sym), ERR_CIRCULAR_REFERENCE);
return GenLiteralExpr (0); /* Return a dummy value */ return GenLiteralExpr (0); /* Return a dummy value */
} }
SymMarkUser (Sym); SymMarkUser (Sym);
Expr = RemoveSyms (GetSymExpr (Sym), 1); Expr = RemoveSyms (GetSymExpr (Sym), 1);
SymUnmarkUser (Sym); SymUnmarkUser (Sym);
return Expr; return Expr;
} else if (SymIsConst (Expr->V.Sym)) { } else if (SymIsConst (Expr->V.Sym)) {
/* The symbol is a constant */ /* The symbol is a constant */
return GenLiteralExpr (GetSymVal (Expr->V.Sym)); return GenLiteralExpr (GetSymVal (Expr->V.Sym));
} }
break; break;
case EXPR_ULABEL: case EXPR_ULABEL:
if (ULabCanResolve ()) { if (ULabCanResolve ()) {
ExprNode* NewExpr = ULabResolve (Expr->V.Val); ExprNode* NewExpr = ULabResolve (Expr->V.Val);
FreeExpr (Expr); FreeExpr (Expr);
Expr = NewExpr; Expr = NewExpr;
} }
break; break;
@ -1436,46 +1418,46 @@ static ExprNode* RemoveSyms (ExprNode* Expr, int MustClone)
/* Clone the current node if needed */ /* Clone the current node if needed */
if (MustClone) { if (MustClone) {
/* Create a new node */ ExprNode* Clone;
ExprNode* Clone = NewExprNode ();
/* Clone the operation */ /* Clone the expression tree */
Clone->Op = Expr->Op;
/* Clone the attribute if needed */
switch (Expr->Op) { switch (Expr->Op) {
case EXPR_LITERAL: case EXPR_LITERAL:
Clone = GenLiteralExpr (Expr->V.Val);
break;
case EXPR_ULABEL: case EXPR_ULABEL:
Clone->V.Val = Expr->V.Val; Clone = GenULabelExpr (Expr->V.Val);
break; break;
case EXPR_SYMBOL: case EXPR_SYMBOL:
Clone->V.Sym = Expr->V.Sym; Clone = GenSymExpr (Expr->V.Sym);
break; break;
case EXPR_SECTION: case EXPR_SECTION:
Clone->V.SegNum = Expr->V.SegNum; Clone = GenSectionExpr (Expr->V.SegNum);
break; break;
default:
Clone = NewExprNode (Expr->Op);
Clone->Left = RemoveSyms (Expr->Left, 1);
Clone->Right = RemoveSyms (Expr->Right, 1);
break;
} }
/* Clone the tree nodes */
Clone->Left = RemoveSyms (Expr->Left, MustClone);
Clone->Right = RemoveSyms (Expr->Right, MustClone);
/* Done */ /* Done */
return Clone; return Clone;
} else { } else {
/* Nothing to clone */ /* Nothing to clone */
Expr->Left = RemoveSyms (Expr->Left, MustClone); Expr->Left = RemoveSyms (Expr->Left, 0);
Expr->Right = RemoveSyms (Expr->Right, MustClone); Expr->Right = RemoveSyms (Expr->Right, 0);
/* Done */ /* Done */
return Expr; return Expr;
} }
} }
@ -1560,8 +1542,7 @@ ExprNode* FinalizeExpr (ExprNode* Expr)
Expr = GenLiteralExpr (Val); Expr = GenLiteralExpr (Val);
} else if (Val) { } else if (Val) {
/* Extracted a value */ /* Extracted a value */
N = NewExprNode (); N = NewExprNode (EXPR_PLUS);
N->Op = EXPR_PLUS;
N->Left = Expr; N->Left = Expr;
N->Right = GenLiteralExpr (Val); N->Right = GenLiteralExpr (Val);
Expr = N; Expr = N;
@ -1583,34 +1564,34 @@ ExprNode* CloneExpr (ExprNode* Expr)
return 0; return 0;
} }
/* Get a new node */ /* Clone the node */
Clone = NewExprNode ();
/* Clone the operation */
Clone->Op = Expr->Op;
/* Clone the attribute if needed */
switch (Expr->Op) { switch (Expr->Op) {
case EXPR_LITERAL: case EXPR_LITERAL:
Clone = GenLiteralExpr (Expr->V.Val);
break;
case EXPR_ULABEL: case EXPR_ULABEL:
Clone->V.Val = Expr->V.Val; Clone = GenULabelExpr (Expr->V.Val);
break; break;
case EXPR_SYMBOL: case EXPR_SYMBOL:
Clone->V.Sym = Expr->V.Sym; Clone = GenSymExpr (Expr->V.Sym);
break; break;
case EXPR_SECTION: case EXPR_SECTION:
Clone->V.SegNum = Expr->V.SegNum; Clone = GenSectionExpr (Expr->V.SegNum);
break; break;
default:
/* Generate a new node */
Clone = NewExprNode (Expr->Op);
/* Clone the tree nodes */
Clone->Left = CloneExpr (Expr->Left);
Clone->Right = CloneExpr (Expr->Right);
break;
} }
/* Clone the tree nodes */
Clone->Left = CloneExpr (Expr->Left);
Clone->Right = CloneExpr (Expr->Right);
/* Done */ /* Done */
return Clone; return Clone;
} }
@ -1663,3 +1644,4 @@ void WriteExpr (ExprNode* Expr)

View File

@ -66,6 +66,9 @@ void FreeExpr (ExprNode* Root);
ExprNode* GenLiteralExpr (long Val); ExprNode* GenLiteralExpr (long Val);
/* Return an expression tree that encodes the given literal value */ /* Return an expression tree that encodes the given literal value */
ExprNode* GenSymExpr (struct SymEntry* Sym);
/* Return an expression node that encodes the given symbol */
ExprNode* GenCurrentPC (void); ExprNode* GenCurrentPC (void);
/* Return the current program counter as expression */ /* Return the current program counter as expression */

View File

@ -519,7 +519,7 @@ int main (int argc, char* argv [])
/* Enter the base lexical level. We must do that here, since we may /* Enter the base lexical level. We must do that here, since we may
* define symbols using -D. * define symbols using -D.
*/ */
SymEnterLevel (); SymEnterLevel (0);
/* Check the parameters */ /* Check the parameters */
I = 1; I = 1;

View File

@ -10,7 +10,8 @@ CC = gcc
EBIND = emxbind EBIND = emxbind
LDFLAGS = LDFLAGS =
OBJS = asserts.o \ OBJS = anonname.o \
asserts.o \
condasm.o \ condasm.o \
dbginfo.o \ dbginfo.o \
ea.o \ ea.o \

View File

@ -43,7 +43,8 @@ CFLAGS += -i=..\common
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
# All library OBJ files # All library OBJ files
OBJS = asserts.obj \ OBJS = anonname.obj \
asserts.obj \
condasm.obj \ condasm.obj \
dbginfo.obj \ dbginfo.obj \
ea.obj \ ea.obj \

View File

@ -49,6 +49,7 @@
#include "xmalloc.h" #include "xmalloc.h"
/* ca65 */ /* ca65 */
#include "anonname.h"
#include "asserts.h" #include "asserts.h"
#include "condasm.h" #include "condasm.h"
#include "dbginfo.h" #include "dbginfo.h"
@ -1248,10 +1249,13 @@ static void DoProc (void)
if (IsZPSeg ()) { if (IsZPSeg ()) {
Flags |= SYM_ZP; Flags |= SYM_ZP;
} }
SymDef (SVal, GenCurrentPC (), Flags); SymDef (SVal, GenCurrentPC (), Flags);
NextTok (); SymEnterLevel (SVal);
NextTok ();
} else {
char Buf[sizeof (SVal)];
SymEnterLevel (AnonName (Buf, sizeof (Buf), "Scope"));
} }
SymEnterLevel ();
} }

View File

@ -60,17 +60,11 @@ SymEntry* SymList = 0; /* List of all symbol table entries */
SymEntry* NewSymEntry (const char* Name) SymEntry* NewSymEntry (unsigned Name)
/* Allocate a symbol table entry, initialize and return it */ /* Allocate a symbol table entry, initialize and return it */
{ {
SymEntry* S;
unsigned Len;
/* Get the length of the name */
Len = strlen (Name);
/* Allocate memory */ /* Allocate memory */
S = xmalloc (sizeof (SymEntry) + Len); SymEntry* S = xmalloc (sizeof (SymEntry));
/* Initialize the entry */ /* Initialize the entry */
S->Left = 0; S->Left = 0;
@ -80,8 +74,9 @@ SymEntry* NewSymEntry (const char* Name)
S->Pos = CurPos; S->Pos = CurPos;
S->Flags = 0; S->Flags = 0;
S->V.Expr = 0; S->V.Expr = 0;
S->ExprRefs = AUTO_COLLECTION_INITIALIZER;
memset (S->ConDesPrio, 0, sizeof (S->ConDesPrio)); memset (S->ConDesPrio, 0, sizeof (S->ConDesPrio));
memcpy (S->Name, Name, Len+1); S->Name = Name;
/* Insert it into the list of all entries */ /* Insert it into the list of all entries */
S->List = SymList; S->List = SymList;
@ -92,4 +87,4 @@ SymEntry* NewSymEntry (const char* Name)
} }

View File

@ -40,6 +40,7 @@
/* common */ /* common */
#include "cddefs.h" #include "cddefs.h"
#include "coll.h"
#include "filepos.h" #include "filepos.h"
@ -52,12 +53,12 @@
/* Bits for the Flags value in SymEntry */ /* Bits for the Flags value in SymEntry */
#define SF_NONE 0x0000 /* Empty flag set */ #define SF_NONE 0x0000 /* Empty flag set */
#define SF_USER 0x0001 /* User bit */ #define SF_USER 0x0001 /* User bit */
#define SF_TRAMPOLINE 0x0002 /* Trampoline entry */ #define SF_TRAMPOLINE 0x0002 /* Trampoline entry */
#define SF_EXPORT 0x0004 /* Export this symbol */ #define SF_EXPORT 0x0004 /* Export this symbol */
#define SF_IMPORT 0x0008 /* Import this symbol */ #define SF_IMPORT 0x0008 /* Import this symbol */
#define SF_GLOBAL 0x0010 /* Global symbol */ #define SF_GLOBAL 0x0010 /* Global symbol */
#define SF_ZP 0x0020 /* Declared as zeropage symbol */ #define SF_ZP 0x0020 /* Declared as zeropage symbol */
#define SF_ABS 0x0040 /* Declared as absolute symbol */ #define SF_ABS 0x0040 /* Declared as absolute symbol */
#define SF_LABEL 0x0080 /* Used as a label */ #define SF_LABEL 0x0080 /* Used as a label */
#define SF_FORCED 0x0100 /* Forced import, SF_IMPORT also set */ #define SF_FORCED 0x0100 /* Forced import, SF_IMPORT also set */
@ -84,9 +85,10 @@ struct SymEntry {
long Val; /* Value (if CONST set) */ long Val; /* Value (if CONST set) */
SymEntry* Sym; /* Symbol (if trampoline entry) */ SymEntry* Sym; /* Symbol (if trampoline entry) */
} V; } V;
Collection ExprRefs; /* Expressions using this symbol */
unsigned char ConDesPrio[CD_TYPE_COUNT]; /* ConDes priorities... */ unsigned char ConDesPrio[CD_TYPE_COUNT]; /* ConDes priorities... */
/* ...actually value+1 (used as flag) */ /* ...actually value+1 (used as flag) */
char Name [1]; /* Dynamic allocation */ unsigned Name; /* Name index in global string pool */
}; };
/* List of all symbol table entries */ /* List of all symbol table entries */
@ -95,14 +97,34 @@ extern SymEntry* SymList;
/*****************************************************************************/ /*****************************************************************************/
/* Code */ /* Code */
/*****************************************************************************/ /*****************************************************************************/
SymEntry* NewSymEntry (const char* Name); SymEntry* NewSymEntry (unsigned Name);
/* Allocate a symbol table entry, initialize and return it */ /* Allocate a symbol table entry, initialize and return it */
#if defined(HAVE_INLINE)
INLINE void SymAddRef (SymEntry* Sym, struct ExprNode* Expr)
/* Add a reference to this symbol */
{
CollAppend (&Sym->ExprRefs, Expr);
}
#else
#define SymAddRef(Sym,Expr) CollAppend (&(Sym)->ExprRefs, Expr)
#endif
#if defined(HAVE_INLINE)
INLINE void SymDelRef (SymEntry* Sym, struct ExprNode* Expr)
/* Delete a reference to this symbol */
{
CollDeleteItem (&Sym->ExprRefs, Expr);
}
#else
#define SymDelRef(Sym,Expr) CollDeleteItem (&(Sym)->ExprRefs, Expr)
#endif
/* End of symentry.h */ /* End of symentry.h */

View File

@ -71,9 +71,14 @@
#define SUB_HASHTAB_SIZE 53 #define SUB_HASHTAB_SIZE 53
typedef struct SymTable SymTable; typedef struct SymTable SymTable;
struct SymTable { struct SymTable {
SymTable* Left; /* Pointer to smaller entry */
SymTable* Right; /* Pointer to greater entry */
SymTable* Parent; /* Link to enclosing scope if any */
SymTable* Childs; /* Pointer to child scopes */
unsigned Level; /* Lexical level */
unsigned TableSlots; /* Number of hash table slots */ unsigned TableSlots; /* Number of hash table slots */
unsigned TableEntries; /* Number of entries in the table */ unsigned TableEntries; /* Number of entries in the table */
SymTable* BackLink; /* Link to enclosing scope if any */ unsigned Name; /* Name of the scope */
SymEntry* Table [1]; /* Dynamic allocation */ SymEntry* Table [1]; /* Dynamic allocation */
}; };
@ -96,7 +101,7 @@ static unsigned ExportCount = 0;/* Counter for export symbols */
static int IsLocal (const char* Name) static int IsLocalName (const char* Name)
/* Return true if Name is the name of a local symbol */ /* Return true if Name is the name of a local symbol */
{ {
return (*Name == LocalStart); return (*Name == LocalStart);
@ -104,20 +109,81 @@ static int IsLocal (const char* Name)
static SymTable* NewSymTable (unsigned Size) static int IsLocalNameId (unsigned Name)
/* Return true if Name is the name of a local symbol */
{
return (*GetString (Name) == LocalStart);
}
static unsigned SymTableSize (unsigned Level)
/* Get the size of a table for the given lexical level */
{
switch (Level) {
case 0: return 213;
case 1: return 53;
default: return 29;
}
}
static SymTable* NewSymTable (SymTable* Parent, unsigned Name)
/* Allocate a symbol table on the heap and return it */ /* Allocate a symbol table on the heap and return it */
{ {
SymTable* S; /* Determine the lexical level and the number of table slots */
unsigned Level = Parent? Parent->Level + 1 : 0;
unsigned Slots = SymTableSize (Level);
/* Allocate memory */ /* Allocate memory */
S = xmalloc (sizeof (SymTable) + (Size-1) * sizeof (SymEntry*)); SymTable* S = xmalloc (sizeof (SymTable) + (Slots-1) * sizeof (SymEntry*));
/* Set variables and clear hash table entries */ /* Set variables and clear hash table entries */
S->TableSlots = Size; S->Left = 0;
S->Right = 0;
S->Childs = 0;
S->Level = Level;
S->TableSlots = Slots;
S->TableEntries = 0; S->TableEntries = 0;
S->BackLink = 0; S->Parent = Parent;
while (Size--) { S->Name = Name;
S->Table [Size] = 0; while (Slots--) {
S->Table[Slots] = 0;
}
/* Insert the symbol table into the child tree of the parent */
if (Parent) {
SymTable* T = Parent->Childs;
if (T == 0) {
/* First entry */
Parent->Childs = S;
} else {
while (1) {
/* Choose next entry */
if (S->Name < T->Name) {
if (T->Left) {
T = T->Left;
} else {
T->Left = S;
break;
}
} else if (S->Name > T->Name) {
if (T->Right) {
T = T->Right;
} else {
T->Right = S;
break;
}
} else {
/* Duplicate scope name */
Internal ("Duplicate scope name: `%s'", GetString (S->Name));
}
}
}
} else {
/* This is the root table */
RootTab = S;
} }
/* Return the prepared struct */ /* Return the prepared struct */
@ -126,53 +192,54 @@ static SymTable* NewSymTable (unsigned Size)
static int SearchSymTab (SymEntry* T, const char* Name, SymEntry** E) static int SearchSymTree (SymEntry* T, unsigned Name, SymEntry** E)
/* Search in the given table for a name (Hash is the hash value of Name and /* Search in the given tree for a name. If we find the symbol, the function
* is given as parameter so that it will not get calculated twice if we search * will return 0 and put the entry pointer into E. If we did not find the
* in more than one table). If we find the symbol, the function will return 0 * symbol, and the tree is empty, E is set to NULL. If the tree is not empty,
* and put the entry pointer into E. If we did not find the symbol, and the * E will be set to the last entry, and the result of the function is <0 if
* tree is empty, E is set to NULL. If the tree is not empty, E will be set to * the entry should be inserted on the left side, and >0 if it should get
* the last entry, and the result of the function is <0 if the entry should * inserted on the right side.
* be inserted on the left side, and >0 if it should get inserted on the right
* side.
*/ */
{ {
int Cmp; int Cmp;
/* Is there a tree? */ /* Is there a tree? */
if (T == 0) { if (T == 0) {
*E = 0; *E = 0;
return 1; return 1;
} }
/* We have a table, search it */ /* We have a table, search it */
while (1) { while (1) {
/* Choose next entry */ /* Choose next entry */
Cmp = strcmp (Name, T->Name); if (Name < T->Name) {
if (Cmp < 0 && T->Left) { Cmp = -1;
} else if (Name > T->Name) {
Cmp = +1;
} else {
Cmp = 0;
}
if (Name < T->Name && T->Left) {
T = T->Left; T = T->Left;
} else if (Cmp > 0 && T->Right) { } else if (Name > T->Name && T->Right) {
T = T->Right; T = T->Right;
} else { } else {
/* Found or end of search */ /* Found or end of search, return the result */
break; *E = T;
return Cmp;
} }
} }
/* Return the search result */
*E = T;
return Cmp;
} }
/*****************************************************************************/ /*****************************************************************************/
/* Code */ /* Code */
/*****************************************************************************/ /*****************************************************************************/
static SymEntry* SymFind (SymTable* Tab, const char* Name, int AllocNew) static SymEntry* SymFind (SymTable* Tab, unsigned Name, int AllocNew)
/* Find a new symbol table entry in the given table. If AllocNew is given and /* Find a new symbol table entry in the given table. If AllocNew is given and
* the entry is not found, create a new one. Return the entry found, or the * the entry is not found, create a new one. Return the entry found, or the
* new entry created, or - in case AllocNew is zero - return 0. * new entry created, or - in case AllocNew is zero - return 0.
@ -182,7 +249,7 @@ static SymEntry* SymFind (SymTable* Tab, const char* Name, int AllocNew)
int Cmp; int Cmp;
unsigned Hash; unsigned Hash;
if (IsLocal (Name)) { if (IsLocalNameId (Name)) {
/* Local symbol, get the table */ /* Local symbol, get the table */
if (!SymLast) { if (!SymLast) {
@ -196,7 +263,7 @@ static SymEntry* SymFind (SymTable* Tab, const char* Name, int AllocNew)
} }
/* Search for the symbol if we have a table */ /* Search for the symbol if we have a table */
Cmp = SearchSymTab (SymLast->Locals, Name, &S); Cmp = SearchSymTree (SymLast->Locals, Name, &S);
/* If we found an entry, return it */ /* If we found an entry, return it */
if (Cmp == 0) { if (Cmp == 0) {
@ -220,21 +287,20 @@ static SymEntry* SymFind (SymTable* Tab, const char* Name, int AllocNew)
} else { } else {
/* Global symbol: Get the hash value for the name */ /* Global symbol: Get the hash value for the name */
Hash = HashStr (Name) % Tab->TableSlots; Hash = Name % Tab->TableSlots;
/* Search for the entry */ /* Search for the entry */
Cmp = SearchSymTab (Tab->Table [Hash], Name, &S); Cmp = SearchSymTree (Tab->Table[Hash], Name, &S);
/* If we found an entry, return it */ /* If we found an entry, return it */
if (Cmp == 0) { if (Cmp == 0) {
/* Check for a trampoline entry, in this case return the real /* Check for a trampoline entry, in this case return the real
* symbol. * symbol.
*/ */
if (S->Flags & SF_TRAMPOLINE) { while (S->Flags & SF_TRAMPOLINE) {
return S->V.Sym; S = S->V.Sym;
} else {
return S;
} }
return S;
} }
if (AllocNew) { if (AllocNew) {
@ -242,7 +308,7 @@ static SymEntry* SymFind (SymTable* Tab, const char* Name, int AllocNew)
/* Otherwise create a new entry, insert and return it */ /* Otherwise create a new entry, insert and return it */
SymEntry* N = NewSymEntry (Name); SymEntry* N = NewSymEntry (Name);
if (S == 0) { if (S == 0) {
Tab->Table [Hash] = N; Tab->Table[Hash] = N;
} else if (Cmp < 0) { } else if (Cmp < 0) {
S->Left = N; S->Left = N;
} else { } else {
@ -261,7 +327,7 @@ static SymEntry* SymFind (SymTable* Tab, const char* Name, int AllocNew)
static SymEntry* SymFindAny (SymTable* Tab, const char* Name) static SymEntry* SymFindAny (SymTable* Tab, unsigned Name)
/* Find a symbol in any table */ /* Find a symbol in any table */
{ {
SymEntry* Sym; SymEntry* Sym;
@ -272,8 +338,8 @@ static SymEntry* SymFindAny (SymTable* Tab, const char* Name)
/* Found, return it */ /* Found, return it */
return Sym; return Sym;
} else { } else {
/* Not found, search in the backlink, if we have one */ /* Not found, search in the parent scope, if we have one */
Tab = Tab->BackLink; Tab = Tab->Parent;
} }
} while (Sym == 0 && Tab != 0); } while (Sym == 0 && Tab != 0);
@ -283,18 +349,16 @@ static SymEntry* SymFindAny (SymTable* Tab, const char* Name)
void SymEnterLevel (void) void SymEnterLevel (const char* ScopeName)
/* Enter a new lexical level */ /* Enter a new lexical level */
{ {
if (RootTab == 0) { /* Accept NULL pointers for the scope name */
/* Create the main symbol table */ if (ScopeName == 0) {
RootTab = SymTab = NewSymTable (MAIN_HASHTAB_SIZE); ScopeName = "";
} else {
/* Create a local symbol table */
SymTable* LocalSyms = NewSymTable (SUB_HASHTAB_SIZE);
LocalSyms->BackLink = SymTab;
SymTab = LocalSyms;
} }
/* Create the new table */
SymTab = NewSymTable (SymTab, GetStringId (ScopeName));
} }
@ -302,7 +366,7 @@ void SymEnterLevel (void)
void SymLeaveLevel (void) void SymLeaveLevel (void)
/* Leave the current lexical level */ /* Leave the current lexical level */
{ {
SymTab = SymTab->BackLink; SymTab = SymTab->Parent;
} }
@ -319,7 +383,7 @@ void SymDef (const char* Name, ExprNode* Expr, unsigned Flags)
/* Define a new symbol */ /* Define a new symbol */
{ {
/* Do we have such a symbol? */ /* Do we have such a symbol? */
SymEntry* S = SymFind (SymTab, Name, SF_ALLOC_NEW); SymEntry* S = SymFind (SymTab, GetStringId (Name), SF_ALLOC_NEW);
if (S->Flags & SF_IMPORT) { if (S->Flags & SF_IMPORT) {
/* Defined symbol is marked as imported external symbol */ /* Defined symbol is marked as imported external symbol */
Error (ERR_SYM_ALREADY_IMPORT, Name); Error (ERR_SYM_ALREADY_IMPORT, Name);
@ -359,7 +423,7 @@ void SymDef (const char* Name, ExprNode* Expr, unsigned Flags)
} }
/* If this is not a local symbol, remember it as the last global one */ /* If this is not a local symbol, remember it as the last global one */
if (!IsLocal (Name)) { if (!IsLocalName (Name)) {
SymLast = S; SymLast = S;
} }
} }
@ -370,10 +434,11 @@ SymEntry* SymRef (const char* Name, int Scope)
/* Search for the symbol and return it */ /* Search for the symbol and return it */
{ {
SymEntry* S; SymEntry* S;
unsigned NameId = GetStringId (Name);
switch (Scope) { switch (Scope) {
case SCOPE_GLOBAL: S = SymFind (RootTab, Name, SF_ALLOC_NEW); break; case SCOPE_GLOBAL: S = SymFind (RootTab, NameId, SF_ALLOC_NEW); break;
case SCOPE_LOCAL: S = SymFind (SymTab, Name, SF_ALLOC_NEW); break; case SCOPE_LOCAL: S = SymFind (SymTab, NameId, SF_ALLOC_NEW); break;
/* Others are not allowed */ /* Others are not allowed */
case SCOPE_ANY: case SCOPE_ANY:
@ -398,13 +463,13 @@ static void SymImportInternal (const char* Name, unsigned Flags)
SymEntry* S; SymEntry* S;
/* Don't accept local symbols */ /* Don't accept local symbols */
if (IsLocal (Name)) { if (IsLocalName (Name)) {
Error (ERR_ILLEGAL_LOCAL_USE); Error (ERR_ILLEGAL_LOCAL_USE);
return; return;
} }
/* Do we have such a symbol? */ /* Do we have such a symbol? */
S = SymFind (SymTab, Name, SF_ALLOC_NEW); S = SymFind (SymTab, GetStringId (Name), SF_ALLOC_NEW);
if (S->Flags & SF_DEFINED) { if (S->Flags & SF_DEFINED) {
Error (ERR_SYM_ALREADY_DEFINED, Name); Error (ERR_SYM_ALREADY_DEFINED, Name);
S->Flags |= SF_MULTDEF; S->Flags |= SF_MULTDEF;
@ -462,13 +527,13 @@ static void SymExportInternal (const char* Name, unsigned Flags)
SymEntry* S; SymEntry* S;
/* Don't accept local symbols */ /* Don't accept local symbols */
if (IsLocal (Name)) { if (IsLocalName (Name)) {
Error (ERR_ILLEGAL_LOCAL_USE); Error (ERR_ILLEGAL_LOCAL_USE);
return; return;
} }
/* Do we have such a symbol? */ /* Do we have such a symbol? */
S = SymFind (SymTab, Name, SF_ALLOC_NEW); S = SymFind (SymTab, GetStringId (Name), SF_ALLOC_NEW);
if (S->Flags & SF_IMPORT) { if (S->Flags & SF_IMPORT) {
/* The symbol is already marked as imported external symbol */ /* The symbol is already marked as imported external symbol */
Error (ERR_SYM_ALREADY_IMPORT, Name); Error (ERR_SYM_ALREADY_IMPORT, Name);
@ -515,13 +580,13 @@ static void SymGlobalInternal (const char* Name, unsigned Flags)
SymEntry* S; SymEntry* S;
/* Don't accept local symbols */ /* Don't accept local symbols */
if (IsLocal (Name)) { if (IsLocalName (Name)) {
Error (ERR_ILLEGAL_LOCAL_USE); Error (ERR_ILLEGAL_LOCAL_USE);
return; return;
} }
/* Search for this symbol, create a new entry if needed */ /* Search for this symbol, create a new entry if needed */
S = SymFind (SymTab, Name, SF_ALLOC_NEW); S = SymFind (SymTab, GetStringId (Name), SF_ALLOC_NEW);
/* If the symbol is already marked as import or export, check the /* If the symbol is already marked as import or export, check the
* size of the definition, then bail out. */ * size of the definition, then bail out. */
@ -574,13 +639,13 @@ void SymConDes (const char* Name, unsigned Type, unsigned Prio)
CHECK (Prio >= CD_PRIO_MIN && Prio <= CD_PRIO_MAX); CHECK (Prio >= CD_PRIO_MIN && Prio <= CD_PRIO_MAX);
/* Don't accept local symbols */ /* Don't accept local symbols */
if (IsLocal (Name)) { if (IsLocalName (Name)) {
Error (ERR_ILLEGAL_LOCAL_USE); Error (ERR_ILLEGAL_LOCAL_USE);
return; return;
} }
/* Do we have such a symbol? */ /* Do we have such a symbol? */
S = SymFind (SymTab, Name, SF_ALLOC_NEW); S = SymFind (SymTab, GetStringId (Name), SF_ALLOC_NEW);
if (S->Flags & SF_IMPORT) { if (S->Flags & SF_IMPORT) {
/* The symbol is already marked as imported external symbol */ /* The symbol is already marked as imported external symbol */
Error (ERR_SYM_ALREADY_IMPORT, Name); Error (ERR_SYM_ALREADY_IMPORT, Name);
@ -618,11 +683,14 @@ int SymIsDef (const char* Name, int Scope)
{ {
SymEntry* S = 0; SymEntry* S = 0;
/* Get the string pool index for the name */
unsigned NameId = GetStringId (Name);
/* Search for the symbol */ /* Search for the symbol */
switch (Scope) { switch (Scope) {
case SCOPE_ANY: S = SymFindAny (SymTab, Name); break; case SCOPE_ANY: S = SymFindAny (SymTab, NameId); break;
case SCOPE_GLOBAL: S = SymFind (RootTab, Name, SF_FIND_EXISTING); break; case SCOPE_GLOBAL: S = SymFind (RootTab, NameId, SF_FIND_EXISTING); break;
case SCOPE_LOCAL: S = SymFind (SymTab, Name, SF_FIND_EXISTING); break; case SCOPE_LOCAL: S = SymFind (SymTab, NameId, SF_FIND_EXISTING); break;
default: Internal ("Invalid scope in SymIsDef: %d", Scope); default: Internal ("Invalid scope in SymIsDef: %d", Scope);
} }
@ -637,11 +705,14 @@ int SymIsRef (const char* Name, int Scope)
{ {
SymEntry* S = 0; SymEntry* S = 0;
/* Get the string pool index for the name */
unsigned NameId = GetStringId (Name);
/* Search for the symbol */ /* Search for the symbol */
switch (Scope) { switch (Scope) {
case SCOPE_ANY: S = SymFindAny (SymTab, Name); break; case SCOPE_ANY: S = SymFindAny (SymTab, NameId); break;
case SCOPE_GLOBAL: S = SymFind (RootTab, Name, SF_FIND_EXISTING); break; case SCOPE_GLOBAL: S = SymFind (RootTab, NameId, SF_FIND_EXISTING); break;
case SCOPE_LOCAL: S = SymFind (SymTab, Name, SF_FIND_EXISTING); break; case SCOPE_LOCAL: S = SymFind (SymTab, NameId, SF_FIND_EXISTING); break;
default: Internal ("Invalid scope in SymIsRef: %d", Scope); default: Internal ("Invalid scope in SymIsRef: %d", Scope);
} }
@ -687,12 +758,12 @@ int SymIsZP (SymEntry* S)
* enclosing scope for a symbol with the same name, and return the ZP * enclosing scope for a symbol with the same name, and return the ZP
* attribute of this symbol if we find one. * attribute of this symbol if we find one.
*/ */
if (!IsLocal (S->Name) && if (!IsLocalNameId (S->Name) &&
(S->Flags & (SF_ZP | SF_ABS | SF_DEFINED | SF_IMPORT)) == 0 && (S->Flags & (SF_ZP | SF_ABS | SF_DEFINED | SF_IMPORT)) == 0 &&
S->SymTab->BackLink != 0) { S->SymTab->Parent != 0) {
/* Try to find a symbol with the same name in the enclosing scope */ /* Try to find a symbol with the same name in the enclosing scope */
SymEntry* E = SymFindAny (S->SymTab->BackLink, S->Name); SymEntry* E = SymFindAny (S->SymTab->Parent, S->Name);
/* If we found one, use the ZP flag */ /* If we found one, use the ZP flag */
if (E && (E->Flags & SF_ZP) != 0) { if (E && (E->Flags & SF_ZP) != 0) {
@ -830,7 +901,7 @@ const char* GetSymName (SymEntry* S)
if (S->Flags & SF_TRAMPOLINE) { if (S->Flags & SF_TRAMPOLINE) {
S = S->V.Sym; S = S->V.Sym;
} }
return S->Name; return GetString (S->Name);
} }
@ -877,7 +948,7 @@ static void SymCheckUndefined (SymEntry* S)
SymEntry* Sym = 0; SymEntry* Sym = 0;
if (S->SymTab) { if (S->SymTab) {
/* It's a global symbol, get the higher level table */ /* It's a global symbol, get the higher level table */
SymTable* Tab = S->SymTab->BackLink; SymTable* Tab = S->SymTab->Parent;
while (Tab) { while (Tab) {
Sym = SymFindAny (Tab, S->Name); Sym = SymFindAny (Tab, S->Name);
if (Sym) { if (Sym) {
@ -888,7 +959,7 @@ static void SymCheckUndefined (SymEntry* S)
break; break;
} else { } else {
/* The symbol found is undefined itself. Look further */ /* The symbol found is undefined itself. Look further */
Tab = Sym->SymTab->BackLink; Tab = Sym->SymTab->Parent;
} }
} else { } else {
/* No symbol found */ /* No symbol found */
@ -910,7 +981,7 @@ static void SymCheckUndefined (SymEntry* S)
if (S->Flags & SF_EXPORT) { if (S->Flags & SF_EXPORT) {
if (Sym->Flags & SF_IMPORT) { if (Sym->Flags & SF_IMPORT) {
/* The symbol is already marked as imported external symbol */ /* The symbol is already marked as imported external symbol */
PError (&S->Pos, ERR_SYM_ALREADY_IMPORT, S->Name); PError (&S->Pos, ERR_SYM_ALREADY_IMPORT, GetString (S->Name));
} }
Sym->Flags |= S->Flags & (SF_EXPORT | SF_ZP); Sym->Flags |= S->Flags & (SF_EXPORT | SF_ZP);
} }
@ -922,14 +993,14 @@ static void SymCheckUndefined (SymEntry* S)
/* The symbol is definitely undefined */ /* The symbol is definitely undefined */
if (S->Flags & SF_EXPORT) { if (S->Flags & SF_EXPORT) {
/* We will not auto-import an export */ /* We will not auto-import an export */
PError (&S->Pos, ERR_EXPORT_UNDEFINED, S->Name); PError (&S->Pos, ERR_EXPORT_UNDEFINED, GetString (S->Name));
} else { } else {
if (AutoImport) { if (AutoImport) {
/* Mark as import, will be indexed later */ /* Mark as import, will be indexed later */
S->Flags |= SF_IMPORT; S->Flags |= SF_IMPORT;
} else { } else {
/* Error */ /* Error */
PError (&S->Pos, ERR_SYM_UNDEFINED, S->Name); PError (&S->Pos, ERR_SYM_UNDEFINED, GetString (S->Name));
} }
} }
} }
@ -943,7 +1014,7 @@ void SymCheck (void)
SymEntry* S; SymEntry* S;
/* Check for open lexical levels */ /* Check for open lexical levels */
if (SymTab->BackLink != 0) { if (SymTab->Parent != 0) {
Error (ERR_OPEN_PROC); Error (ERR_OPEN_PROC);
} }
@ -984,12 +1055,12 @@ void SymCheck (void)
(S->Flags & SF_UNDEFMASK) != SF_UNDEFVAL) { (S->Flags & SF_UNDEFMASK) != SF_UNDEFVAL) {
if ((S->Flags & SF_DEFINED) != 0 && (S->Flags & SF_REFERENCED) == 0) { if ((S->Flags & SF_DEFINED) != 0 && (S->Flags & SF_REFERENCED) == 0) {
/* Symbol was defined but never referenced */ /* Symbol was defined but never referenced */
PWarning (&S->Pos, WARN_SYM_NOT_REFERENCED, S->Name); PWarning (&S->Pos, WARN_SYM_NOT_REFERENCED, GetString (S->Name));
} }
if (S->Flags & SF_IMPORT) { if (S->Flags & SF_IMPORT) {
if ((S->Flags & (SF_REFERENCED | SF_FORCED)) == SF_NONE) { if ((S->Flags & (SF_REFERENCED | SF_FORCED)) == SF_NONE) {
/* Imported symbol is not referenced */ /* Imported symbol is not referenced */
PWarning (&S->Pos, WARN_IMPORT_NOT_REFERENCED, S->Name); PWarning (&S->Pos, WARN_IMPORT_NOT_REFERENCED, GetString (S->Name));
} else { } else {
/* Give the import an index, count imports */ /* Give the import an index, count imports */
S->Index = ImportCount++; S->Index = ImportCount++;
@ -1020,7 +1091,7 @@ void SymDump (FILE* F)
if ((S->Flags & SF_TRAMPOLINE) != 0) { if ((S->Flags & SF_TRAMPOLINE) != 0) {
fprintf (F, fprintf (F,
"%-24s %s %s %s %s %s\n", "%-24s %s %s %s %s %s\n",
S->Name, GetString (S->Name),
(S->Flags & SF_DEFINED)? "DEF" : "---", (S->Flags & SF_DEFINED)? "DEF" : "---",
(S->Flags & SF_REFERENCED)? "REF" : "---", (S->Flags & SF_REFERENCED)? "REF" : "---",
(S->Flags & SF_IMPORT)? "IMP" : "---", (S->Flags & SF_IMPORT)? "IMP" : "---",
@ -1060,7 +1131,7 @@ void WriteImports (void)
} else { } else {
ObjWrite8 (IMP_ABS); ObjWrite8 (IMP_ABS);
} }
ObjWriteVar (GetStringId (S->Name)); ObjWriteVar (S->Name);
ObjWritePos (&S->Pos); ObjWritePos (&S->Pos);
} }
S = S->List; S = S->List;
@ -1137,7 +1208,7 @@ void WriteExports (void)
} }
/* Write the name */ /* Write the name */
ObjWriteVar (GetStringId (S->Name)); ObjWriteVar (S->Name);
/* Write the value */ /* Write the value */
if ((ExprMask & EXP_MASK_VAL) == EXP_CONST) { if ((ExprMask & EXP_MASK_VAL) == EXP_CONST) {
@ -1201,7 +1272,7 @@ void WriteDbgSyms (void)
ObjWrite8 (ExprMask); ObjWrite8 (ExprMask);
/* Write the name */ /* Write the name */
ObjWriteVar (GetStringId (S->Name)); ObjWriteVar (S->Name);
/* Write the value */ /* Write the value */
if ((ExprMask & EXP_MASK_VAL) == EXP_CONST) { if ((ExprMask & EXP_MASK_VAL) == EXP_CONST) {
@ -1231,3 +1302,4 @@ void WriteDbgSyms (void)

View File

@ -72,7 +72,7 @@
void SymEnterLevel (void); void SymEnterLevel (const char* ScopeName);
/* Enter a new lexical level */ /* Enter a new lexical level */
void SymLeaveLevel (void); void SymLeaveLevel (void);