Added a scope argument to the SymIsDef and SymIsDef functions, so it is

possible to request information for a specific scope.
Add an optional scope argument to the .DEFINED builtin function.
Change the long branch macros to look for symbols in local scope.


git-svn-id: svn://svn.cc65.org/cc65/trunk@1574 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
cuz
2002-11-22 01:45:00 +00:00
parent d7a5fbeb1a
commit 4dd4e76a88
9 changed files with 138 additions and 62 deletions

View File

@@ -6,7 +6,7 @@
/* */ /* */
/* */ /* */
/* */ /* */
/* (C) 2000 Ullrich von Bassewitz */ /* (C) 2000-2002 Ullrich von Bassewitz */
/* Wacholderweg 14 */ /* Wacholderweg 14 */
/* D-70597 Stuttgart */ /* D-70597 Stuttgart */
/* EMail: uz@musoftware.de */ /* EMail: uz@musoftware.de */
@@ -307,7 +307,7 @@ void DoConditionals (void)
if (Tok != TOK_IDENT) { if (Tok != TOK_IDENT) {
ErrorSkip (ERR_IDENT_EXPECTED); ErrorSkip (ERR_IDENT_EXPECTED);
} else { } else {
SetIfCond (D, SymIsDef (SVal)); SetIfCond (D, SymIsDef (SVal, SCOPE_ANY));
NextTok (); NextTok ();
} }
} }
@@ -346,7 +346,7 @@ void DoConditionals (void)
if (Tok != TOK_IDENT) { if (Tok != TOK_IDENT) {
ErrorSkip (ERR_IDENT_EXPECTED); ErrorSkip (ERR_IDENT_EXPECTED);
} else { } else {
SetIfCond (D, !SymIsDef (SVal)); SetIfCond (D, !SymIsDef (SVal, SCOPE_ANY));
NextTok (); NextTok ();
} }
} }
@@ -360,7 +360,7 @@ void DoConditionals (void)
if (Tok != TOK_IDENT) { if (Tok != TOK_IDENT) {
ErrorSkip (ERR_IDENT_EXPECTED); ErrorSkip (ERR_IDENT_EXPECTED);
} else { } else {
SetIfCond (D, !SymIsRef (SVal)); SetIfCond (D, !SymIsRef (SVal, SCOPE_ANY));
NextTok (); NextTok ();
} }
} }
@@ -401,7 +401,7 @@ void DoConditionals (void)
if (Tok != TOK_IDENT) { if (Tok != TOK_IDENT) {
ErrorSkip (ERR_IDENT_EXPECTED); ErrorSkip (ERR_IDENT_EXPECTED);
} else { } else {
SetIfCond (D, SymIsRef (SVal)); SetIfCond (D, SymIsRef (SVal, SCOPE_ANY));
NextTok (); NextTok ();
} }
} }

View File

@@ -158,9 +158,10 @@ void ErrorMsg (const FilePos* Pos, unsigned ErrNum, va_list ap)
"Illegal character to start local symbols", "Illegal character to start local symbols",
"Illegal use of local symbol", "Illegal use of local symbol",
"Illegal segment name: `%s'", "Illegal segment name: `%s'",
"Illegal segment attribute", "Illegal segment attribute",
"Illegal macro package name", "Illegal macro package name",
"Illegal emulation feature", "Illegal emulation feature",
"Illegal scope specifier",
"Syntax error", "Syntax error",
"Symbol `%s' is already defined", "Symbol `%s' is already defined",
"Undefined symbol `%s'", "Undefined symbol `%s'",

View File

@@ -102,6 +102,7 @@ enum Errors {
ERR_ILLEGAL_SEG_ATTR, ERR_ILLEGAL_SEG_ATTR,
ERR_ILLEGAL_MACPACK, ERR_ILLEGAL_MACPACK,
ERR_ILLEGAL_FEATURE, ERR_ILLEGAL_FEATURE,
ERR_ILLEGAL_SCOPE,
ERR_SYNTAX, ERR_SYNTAX,
ERR_SYM_ALREADY_DEFINED, ERR_SYM_ALREADY_DEFINED,
ERR_SYM_UNDEFINED, ERR_SYM_UNDEFINED,

View File

@@ -6,7 +6,7 @@
/* */ /* */
/* */ /* */
/* */ /* */
/* (C) 1998-2000 Ullrich von Bassewitz */ /* (C) 1998-2002 Ullrich von Bassewitz */
/* Wacholderweg 14 */ /* Wacholderweg 14 */
/* D-70597 Stuttgart */ /* D-70597 Stuttgart */
/* EMail: uz@musoftware.de */ /* EMail: uz@musoftware.de */
@@ -199,18 +199,69 @@ static int FuncConst (void)
static int FuncDefined (void) static int FuncDefined (void)
/* Handle the .DEFINED builtin function */ /* Handle the .DEFINED builtin function */
{ {
int Result = 0; static const char* Keys[] = {
"ANY",
"GLOBAL",
"LOCAL",
};
char Name [sizeof (SVal)];
int Result = 0;
int Scope;
/* First argument is a symbol name */
if (Tok != TOK_IDENT) { if (Tok != TOK_IDENT) {
Error (ERR_IDENT_EXPECTED); Error (ERR_IDENT_EXPECTED);
if (Tok != TOK_RPAREN) { if (Tok != TOK_RPAREN) {
NextTok (); NextTok ();
} }
} else { return 0;
Result = SymIsDef (SVal);
NextTok ();
} }
/* Remember the name, then skip it */
strcpy (Name, SVal);
NextTok ();
/* Comma and scope spec may follow */
if (Tok == TOK_COMMA) {
/* Skip the comma */
NextTok ();
/* An identifier must follow */
if (Tok != TOK_IDENT) {
Error (ERR_IDENT_EXPECTED);
return 0;
}
/* Get the scope, then skip it */
Scope = GetSubKey (Keys, sizeof (Keys) / sizeof (Keys [0]));
NextTok ();
/* Check if we got a valid keyword */
if (Scope < 0) {
Error (ERR_ILLEGAL_SCOPE);
return 0;
}
/* Map the scope */
switch (Scope) {
case 0: Scope = SCOPE_ANY; break;
case 1: Scope = SCOPE_GLOBAL; break;
case 2: Scope = SCOPE_LOCAL; break;
default: Internal ("Invalid scope: %d", Scope);
}
} else {
/* Any scope */
Scope = SCOPE_ANY;
}
/* Search for the symbol */
Result = SymIsDef (SVal, Scope);
/* Done */ /* Done */
return Result; return Result;
} }
@@ -325,7 +376,7 @@ static int FuncReferenced (void)
NextTok (); NextTok ();
} }
} else { } else {
Result = SymIsRef (SVal); Result = SymIsRef (SVal, SCOPE_ANY);
NextTok (); NextTok ();
} }
@@ -499,7 +550,7 @@ static ExprNode* Factor (void)
Error (ERR_IDENT_EXPECTED); Error (ERR_IDENT_EXPECTED);
N = LiteralExpr (0); /* Dummy */ N = LiteralExpr (0); /* Dummy */
} else { } else {
S = SymRefGlobal (SVal); S = SymRef (SVal, SCOPE_GLOBAL);
if (SymIsConst (S)) { if (SymIsConst (S)) {
/* Use the literal value instead */ /* Use the literal value instead */
N = LiteralExpr (GetSymVal (S)); N = LiteralExpr (GetSymVal (S));
@@ -514,7 +565,7 @@ static ExprNode* Factor (void)
break; break;
case TOK_IDENT: case TOK_IDENT:
S = SymRef (SVal); S = SymRef (SVal, SCOPE_LOCAL);
if (SymIsConst (S)) { if (SymIsConst (S)) {
/* Use the literal value instead */ /* Use the literal value instead */
N = LiteralExpr (GetSymVal (S)); N = LiteralExpr (GetSymVal (S));

View File

@@ -75,7 +75,7 @@ static const char MacLongBranch [] = /* Long branch macros */
" .if .match(Target, 0)\n" " .if .match(Target, 0)\n"
" bne *+5\n" " bne *+5\n"
" jmp Target\n" " jmp Target\n"
" .elseif .def(Target) .and ((*+2)-(Target) <= 127)\n" " .elseif .def(Target,local) .and ((*+2)-(Target) <= 127)\n"
" beq Target\n" " beq Target\n"
" .else\n" " .else\n"
" bne *+5\n" " bne *+5\n"
@@ -86,7 +86,7 @@ static const char MacLongBranch [] = /* Long branch macros */
" .if .match(Target, 0)\n" " .if .match(Target, 0)\n"
" beq *+5\n" " beq *+5\n"
" jmp Target\n" " jmp Target\n"
" .elseif .def(Target) .and ((*+2)-(Target) <= 127)\n" " .elseif .def(Target,local) .and ((*+2)-(Target) <= 127)\n"
" bne Target\n" " bne Target\n"
" .else\n" " .else\n"
" beq *+5\n" " beq *+5\n"
@@ -97,7 +97,7 @@ static const char MacLongBranch [] = /* Long branch macros */
" .if .match(Target, 0)\n" " .if .match(Target, 0)\n"
" bpl *+5\n" " bpl *+5\n"
" jmp Target\n" " jmp Target\n"
" .elseif .def(Target) .and ((*+2)-(Target) <= 127)\n" " .elseif .def(Target,local) .and ((*+2)-(Target) <= 127)\n"
" bmi Target\n" " bmi Target\n"
" .else\n" " .else\n"
" bpl *+5\n" " bpl *+5\n"
@@ -108,7 +108,7 @@ static const char MacLongBranch [] = /* Long branch macros */
" .if .match(Target, 0)\n" " .if .match(Target, 0)\n"
" bmi *+5\n" " bmi *+5\n"
" jmp Target\n" " jmp Target\n"
" .elseif .def(Target) .and ((*+2)-(Target) <= 127)\n" " .elseif .def(Target,local) .and ((*+2)-(Target) <= 127)\n"
" bpl Target\n" " bpl Target\n"
" .else\n" " .else\n"
" bmi *+5\n" " bmi *+5\n"
@@ -119,7 +119,7 @@ static const char MacLongBranch [] = /* Long branch macros */
" .if .match(Target, 0)\n" " .if .match(Target, 0)\n"
" bcc *+5\n" " bcc *+5\n"
" jmp Target\n" " jmp Target\n"
" .elseif .def(Target) .and ((*+2)-(Target) <= 127)\n" " .elseif .def(Target,local) .and ((*+2)-(Target) <= 127)\n"
" bcs Target\n" " bcs Target\n"
" .else\n" " .else\n"
" bcc *+5\n" " bcc *+5\n"
@@ -130,7 +130,7 @@ static const char MacLongBranch [] = /* Long branch macros */
" .if .match(Target, 0)\n" " .if .match(Target, 0)\n"
" bcs *+5\n" " bcs *+5\n"
" jmp Target\n" " jmp Target\n"
" .elseif .def(Target) .and ((*+2)-(Target) <= 127)\n" " .elseif .def(Target,local) .and ((*+2)-(Target) <= 127)\n"
" bcc Target\n" " bcc Target\n"
" .else\n" " .else\n"
" bcs *+5\n" " bcs *+5\n"
@@ -141,7 +141,7 @@ static const char MacLongBranch [] = /* Long branch macros */
" .if .match(Target, 0)\n" " .if .match(Target, 0)\n"
" bvc *+5\n" " bvc *+5\n"
" jmp Target\n" " jmp Target\n"
" .elseif .def(Target) .and ((*+2)-(Target) <= 127)\n" " .elseif .def(Target,local) .and ((*+2)-(Target) <= 127)\n"
" bvs Target\n" " bvs Target\n"
" .else\n" " .else\n"
" bvc *+5\n" " bvc *+5\n"
@@ -152,7 +152,7 @@ static const char MacLongBranch [] = /* Long branch macros */
" .if .match(Target, 0)\n" " .if .match(Target, 0)\n"
" bvs *+5\n" " bvs *+5\n"
" jmp Target\n" " jmp Target\n"
" .elseif .def(Target) .and ((*+2)-(Target) <= 127)\n" " .elseif .def(Target,local) .and ((*+2)-(Target) <= 127)\n"
" bvc Target\n" " bvc Target\n"
" .else\n" " .else\n"
" bvs *+5\n" " bvs *+5\n"

View File

@@ -176,7 +176,7 @@ static void DefineSymbol (const char* Def)
} }
/* Check if have already a symbol with this name */ /* Check if have already a symbol with this name */
if (SymIsDef (SymName)) { if (SymIsDef (SymName, SCOPE_ANY)) {
AbEnd ("`%s' is already defined", SymName); AbEnd ("`%s' is already defined", SymName);
} }

View File

@@ -360,21 +360,6 @@ static SymEntry* SymFindAny (SymTable* Tab, const char* Name)
static SymEntry* SymRefInternal (SymTable* Table, const char* Name)
/* Search for the symbol in the given table and return it */
{
/* Try to find the symbol, create a new one if the symbol does not exist */
SymEntry* S = SymFind (Table, Name, SF_ALLOC_NEW);
/* Mark the symbol as referenced */
S->Flags |= SF_REFERENCED;
/* Return it */
return S;
}
void SymEnterLevel (void) void SymEnterLevel (void)
/* Enter a new lexical level */ /* Enter a new lexical level */
{ {
@@ -451,20 +436,28 @@ void SymDef (const char* Name, ExprNode* Expr, int ZP, int Label)
SymEntry* SymRef (const char* Name) SymEntry* SymRef (const char* Name, int Scope)
/* Search for the symbol and return it */ /* Search for the symbol and return it */
{ {
/* Reference the symbol in the current table */ SymEntry* S;
return SymRefInternal (SymTab, Name);
}
switch (Scope) {
case SCOPE_GLOBAL: S = SymFind (RootTab, Name, SF_ALLOC_NEW); break;
case SCOPE_LOCAL: S = SymFind (SymTab, Name, SF_ALLOC_NEW); break;
/* Others are not allowed */
case SCOPE_ANY:
default:
Internal ("Invalid scope in SymRef: %d", Scope);
/* NOTREACHED */
S = 0;
}
SymEntry* SymRefGlobal (const char* Name) /* Mark the symbol as referenced */
/* Search for the symbol in the global namespace and return it */ S->Flags |= SF_REFERENCED;
{
/* Reference the symbol in the current table */ /* Return it */
return SymRefInternal (RootTab, Name); return S;
} }
@@ -639,19 +632,39 @@ void SymConDes (const char* Name, unsigned Type, unsigned Prio)
int SymIsDef (const char* Name) int SymIsDef (const char* Name, int Scope)
/* Return true if the given symbol is already defined */ /* Return true if the given symbol is already defined */
{ {
SymEntry* S = SymFindAny (SymTab, Name); SymEntry* S = 0;
/* Search for the symbol */
switch (Scope) {
case SCOPE_ANY: S = SymFindAny (SymTab, Name); break;
case SCOPE_GLOBAL: S = SymFind (RootTab, Name, SF_FIND_EXISTING); break;
case SCOPE_LOCAL: S = SymFind (SymTab, Name, SF_FIND_EXISTING); break;
default: Internal ("Invalid scope in SymIsDef: %d", Scope);
}
/* Check if it's defined */
return S != 0 && (S->Flags & SF_DEFINED) != 0; return S != 0 && (S->Flags & SF_DEFINED) != 0;
} }
int SymIsRef (const char* Name) int SymIsRef (const char* Name, int Scope)
/* Return true if the given symbol has been referenced */ /* Return true if the given symbol has been referenced */
{ {
SymEntry* S = SymFindAny (SymTab, Name); SymEntry* S = 0;
/* Search for the symbol */
switch (Scope) {
case SCOPE_ANY: S = SymFindAny (SymTab, Name); break;
case SCOPE_GLOBAL: S = SymFind (RootTab, Name, SF_FIND_EXISTING); break;
case SCOPE_LOCAL: S = SymFind (SymTab, Name, SF_FIND_EXISTING); break;
default: Internal ("Invalid scope in SymIsRef: %d", Scope);
}
/* Check if it's defined */
return S != 0 && (S->Flags & SF_REFERENCED) != 0; return S != 0 && (S->Flags & SF_REFERENCED) != 0;
} }

View File

@@ -48,6 +48,19 @@
/*****************************************************************************/
/* Data */
/*****************************************************************************/
/* Scope identifiers */
#define SCOPE_ANY 0
#define SCOPE_GLOBAL 1
#define SCOPE_LOCAL 2
/*****************************************************************************/ /*****************************************************************************/
/* Code */ /* Code */
/*****************************************************************************/ /*****************************************************************************/
@@ -63,16 +76,13 @@ void SymLeaveLevel (void);
void SymDef (const char* Name, ExprNode* Expr, int ZP, int Label); void SymDef (const char* Name, ExprNode* Expr, int ZP, int Label);
/* Define a new symbol */ /* Define a new symbol */
SymEntry* SymRef (const char* Name); SymEntry* SymRef (const char* Name, int Scope);
/* Search for the symbol and return it */ /* Search for the symbol and return it */
SymEntry* SymRefGlobal (const char* Name); int SymIsDef (const char* Name, int Scope);
/* Search for the symbol in the global namespace and return it */
int SymIsDef (const char* Name);
/* Return true if the given symbol is already defined */ /* Return true if the given symbol is already defined */
int SymIsRef (const char* Name); int SymIsRef (const char* Name, int Scope);
/* Return true if the given symbol has been referenced */ /* Return true if the given symbol has been referenced */
void SymImport (const char* Name, int ZP); void SymImport (const char* Name, int ZP);