From 4dd4e76a884a4479393a9bcfcfc39c92335e9af1 Mon Sep 17 00:00:00 2001 From: cuz Date: Fri, 22 Nov 2002 01:45:00 +0000 Subject: [PATCH] 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 --- src/ca65/condasm.c | 10 +++---- src/ca65/error.c | 5 ++-- src/ca65/error.h | 1 + src/ca65/expr.c | 63 ++++++++++++++++++++++++++++++++++++---- src/ca65/macpack.c | 16 +++++------ src/ca65/main.c | 2 +- src/ca65/scanner.h | 2 +- src/ca65/symtab.c | 71 +++++++++++++++++++++++++++------------------- src/ca65/symtab.h | 22 ++++++++++---- 9 files changed, 134 insertions(+), 58 deletions(-) diff --git a/src/ca65/condasm.c b/src/ca65/condasm.c index 5d5b4d79d..a270a39a7 100644 --- a/src/ca65/condasm.c +++ b/src/ca65/condasm.c @@ -6,7 +6,7 @@ /* */ /* */ /* */ -/* (C) 2000 Ullrich von Bassewitz */ +/* (C) 2000-2002 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@musoftware.de */ @@ -307,7 +307,7 @@ void DoConditionals (void) if (Tok != TOK_IDENT) { ErrorSkip (ERR_IDENT_EXPECTED); } else { - SetIfCond (D, SymIsDef (SVal)); + SetIfCond (D, SymIsDef (SVal, SCOPE_ANY)); NextTok (); } } @@ -346,7 +346,7 @@ void DoConditionals (void) if (Tok != TOK_IDENT) { ErrorSkip (ERR_IDENT_EXPECTED); } else { - SetIfCond (D, !SymIsDef (SVal)); + SetIfCond (D, !SymIsDef (SVal, SCOPE_ANY)); NextTok (); } } @@ -360,7 +360,7 @@ void DoConditionals (void) if (Tok != TOK_IDENT) { ErrorSkip (ERR_IDENT_EXPECTED); } else { - SetIfCond (D, !SymIsRef (SVal)); + SetIfCond (D, !SymIsRef (SVal, SCOPE_ANY)); NextTok (); } } @@ -401,7 +401,7 @@ void DoConditionals (void) if (Tok != TOK_IDENT) { ErrorSkip (ERR_IDENT_EXPECTED); } else { - SetIfCond (D, SymIsRef (SVal)); + SetIfCond (D, SymIsRef (SVal, SCOPE_ANY)); NextTok (); } } diff --git a/src/ca65/error.c b/src/ca65/error.c index ba4de8269..2145818aa 100644 --- a/src/ca65/error.c +++ b/src/ca65/error.c @@ -158,9 +158,10 @@ void ErrorMsg (const FilePos* Pos, unsigned ErrNum, va_list ap) "Illegal character to start local symbols", "Illegal use of local symbol", "Illegal segment name: `%s'", - "Illegal segment attribute", + "Illegal segment attribute", "Illegal macro package name", - "Illegal emulation feature", + "Illegal emulation feature", + "Illegal scope specifier", "Syntax error", "Symbol `%s' is already defined", "Undefined symbol `%s'", diff --git a/src/ca65/error.h b/src/ca65/error.h index 311b47c2a..043931253 100644 --- a/src/ca65/error.h +++ b/src/ca65/error.h @@ -102,6 +102,7 @@ enum Errors { ERR_ILLEGAL_SEG_ATTR, ERR_ILLEGAL_MACPACK, ERR_ILLEGAL_FEATURE, + ERR_ILLEGAL_SCOPE, ERR_SYNTAX, ERR_SYM_ALREADY_DEFINED, ERR_SYM_UNDEFINED, diff --git a/src/ca65/expr.c b/src/ca65/expr.c index 497a6143a..ce37e9ba7 100644 --- a/src/ca65/expr.c +++ b/src/ca65/expr.c @@ -6,7 +6,7 @@ /* */ /* */ /* */ -/* (C) 1998-2000 Ullrich von Bassewitz */ +/* (C) 1998-2002 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@musoftware.de */ @@ -199,18 +199,69 @@ static int FuncConst (void) static int FuncDefined (void) /* Handle the .DEFINED builtin function */ { + 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) { Error (ERR_IDENT_EXPECTED); if (Tok != TOK_RPAREN) { NextTok (); } + return 0; + } + + /* 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 { - Result = SymIsDef (SVal); - NextTok (); + + /* Any scope */ + Scope = SCOPE_ANY; + } + /* Search for the symbol */ + Result = SymIsDef (SVal, Scope); + /* Done */ return Result; } @@ -325,7 +376,7 @@ static int FuncReferenced (void) NextTok (); } } else { - Result = SymIsRef (SVal); + Result = SymIsRef (SVal, SCOPE_ANY); NextTok (); } @@ -499,7 +550,7 @@ static ExprNode* Factor (void) Error (ERR_IDENT_EXPECTED); N = LiteralExpr (0); /* Dummy */ } else { - S = SymRefGlobal (SVal); + S = SymRef (SVal, SCOPE_GLOBAL); if (SymIsConst (S)) { /* Use the literal value instead */ N = LiteralExpr (GetSymVal (S)); @@ -514,7 +565,7 @@ static ExprNode* Factor (void) break; case TOK_IDENT: - S = SymRef (SVal); + S = SymRef (SVal, SCOPE_LOCAL); if (SymIsConst (S)) { /* Use the literal value instead */ N = LiteralExpr (GetSymVal (S)); diff --git a/src/ca65/macpack.c b/src/ca65/macpack.c index db5c7531f..0d968edba 100644 --- a/src/ca65/macpack.c +++ b/src/ca65/macpack.c @@ -75,7 +75,7 @@ static const char MacLongBranch [] = /* Long branch macros */ " .if .match(Target, 0)\n" " bne *+5\n" " jmp Target\n" - " .elseif .def(Target) .and ((*+2)-(Target) <= 127)\n" + " .elseif .def(Target,local) .and ((*+2)-(Target) <= 127)\n" " beq Target\n" " .else\n" " bne *+5\n" @@ -86,7 +86,7 @@ static const char MacLongBranch [] = /* Long branch macros */ " .if .match(Target, 0)\n" " beq *+5\n" " jmp Target\n" - " .elseif .def(Target) .and ((*+2)-(Target) <= 127)\n" + " .elseif .def(Target,local) .and ((*+2)-(Target) <= 127)\n" " bne Target\n" " .else\n" " beq *+5\n" @@ -97,7 +97,7 @@ static const char MacLongBranch [] = /* Long branch macros */ " .if .match(Target, 0)\n" " bpl *+5\n" " jmp Target\n" - " .elseif .def(Target) .and ((*+2)-(Target) <= 127)\n" + " .elseif .def(Target,local) .and ((*+2)-(Target) <= 127)\n" " bmi Target\n" " .else\n" " bpl *+5\n" @@ -108,7 +108,7 @@ static const char MacLongBranch [] = /* Long branch macros */ " .if .match(Target, 0)\n" " bmi *+5\n" " jmp Target\n" - " .elseif .def(Target) .and ((*+2)-(Target) <= 127)\n" + " .elseif .def(Target,local) .and ((*+2)-(Target) <= 127)\n" " bpl Target\n" " .else\n" " bmi *+5\n" @@ -119,7 +119,7 @@ static const char MacLongBranch [] = /* Long branch macros */ " .if .match(Target, 0)\n" " bcc *+5\n" " jmp Target\n" - " .elseif .def(Target) .and ((*+2)-(Target) <= 127)\n" + " .elseif .def(Target,local) .and ((*+2)-(Target) <= 127)\n" " bcs Target\n" " .else\n" " bcc *+5\n" @@ -130,7 +130,7 @@ static const char MacLongBranch [] = /* Long branch macros */ " .if .match(Target, 0)\n" " bcs *+5\n" " jmp Target\n" - " .elseif .def(Target) .and ((*+2)-(Target) <= 127)\n" + " .elseif .def(Target,local) .and ((*+2)-(Target) <= 127)\n" " bcc Target\n" " .else\n" " bcs *+5\n" @@ -141,7 +141,7 @@ static const char MacLongBranch [] = /* Long branch macros */ " .if .match(Target, 0)\n" " bvc *+5\n" " jmp Target\n" - " .elseif .def(Target) .and ((*+2)-(Target) <= 127)\n" + " .elseif .def(Target,local) .and ((*+2)-(Target) <= 127)\n" " bvs Target\n" " .else\n" " bvc *+5\n" @@ -152,7 +152,7 @@ static const char MacLongBranch [] = /* Long branch macros */ " .if .match(Target, 0)\n" " bvs *+5\n" " jmp Target\n" - " .elseif .def(Target) .and ((*+2)-(Target) <= 127)\n" + " .elseif .def(Target,local) .and ((*+2)-(Target) <= 127)\n" " bvc Target\n" " .else\n" " bvs *+5\n" diff --git a/src/ca65/main.c b/src/ca65/main.c index 6aa28f188..5f7f2ca28 100644 --- a/src/ca65/main.c +++ b/src/ca65/main.c @@ -176,7 +176,7 @@ static void DefineSymbol (const char* Def) } /* Check if have already a symbol with this name */ - if (SymIsDef (SymName)) { + if (SymIsDef (SymName, SCOPE_ANY)) { AbEnd ("`%s' is already defined", SymName); } diff --git a/src/ca65/scanner.h b/src/ca65/scanner.h index 10a8c4e1d..e24397078 100644 --- a/src/ca65/scanner.h +++ b/src/ca65/scanner.h @@ -118,7 +118,7 @@ enum Token { TOK_BLANK, TOK_BSS, TOK_BYTE, - TOK_CASE, + TOK_CASE, TOK_CHARMAP, TOK_CODE, TOK_CONCAT, diff --git a/src/ca65/symtab.c b/src/ca65/symtab.c index a8edcad4d..b447bc65d 100644 --- a/src/ca65/symtab.c +++ b/src/ca65/symtab.c @@ -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) /* 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 */ -{ - /* Reference the symbol in the current table */ - return SymRefInternal (SymTab, Name); -} +{ + SymEntry* S; + 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) -/* Search for the symbol in the global namespace and return it */ -{ - /* Reference the symbol in the current table */ - return SymRefInternal (RootTab, Name); + /* Mark the symbol as referenced */ + S->Flags |= SF_REFERENCED; + + /* Return it */ + 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 */ { - 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; } -int SymIsRef (const char* Name) +int SymIsRef (const char* Name, int Scope) /* 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; } diff --git a/src/ca65/symtab.h b/src/ca65/symtab.h index 642734274..e1d8e39ff 100644 --- a/src/ca65/symtab.h +++ b/src/ca65/symtab.h @@ -48,6 +48,19 @@ +/*****************************************************************************/ +/* Data */ +/*****************************************************************************/ + + + +/* Scope identifiers */ +#define SCOPE_ANY 0 +#define SCOPE_GLOBAL 1 +#define SCOPE_LOCAL 2 + + + /*****************************************************************************/ /* Code */ /*****************************************************************************/ @@ -63,16 +76,13 @@ void SymLeaveLevel (void); void SymDef (const char* Name, ExprNode* Expr, int ZP, int Label); /* Define a new symbol */ -SymEntry* SymRef (const char* Name); +SymEntry* SymRef (const char* Name, int Scope); /* Search for the symbol and return it */ -SymEntry* SymRefGlobal (const char* Name); -/* Search for the symbol in the global namespace and return it */ - -int SymIsDef (const char* Name); +int SymIsDef (const char* Name, int Scope); /* 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 */ void SymImport (const char* Name, int ZP); -- 2.39.5