/* */
/* */
/* */
-/* (C) 2000 Ullrich von Bassewitz */
+/* (C) 2000-2002 Ullrich von Bassewitz */
/* Wacholderweg 14 */
/* D-70597 Stuttgart */
/* EMail: uz@musoftware.de */
if (Tok != TOK_IDENT) {
ErrorSkip (ERR_IDENT_EXPECTED);
} else {
- SetIfCond (D, SymIsDef (SVal));
+ SetIfCond (D, SymIsDef (SVal, SCOPE_ANY));
NextTok ();
}
}
if (Tok != TOK_IDENT) {
ErrorSkip (ERR_IDENT_EXPECTED);
} else {
- SetIfCond (D, !SymIsDef (SVal));
+ SetIfCond (D, !SymIsDef (SVal, SCOPE_ANY));
NextTok ();
}
}
if (Tok != TOK_IDENT) {
ErrorSkip (ERR_IDENT_EXPECTED);
} else {
- SetIfCond (D, !SymIsRef (SVal));
+ SetIfCond (D, !SymIsRef (SVal, SCOPE_ANY));
NextTok ();
}
}
if (Tok != TOK_IDENT) {
ErrorSkip (ERR_IDENT_EXPECTED);
} else {
- SetIfCond (D, SymIsRef (SVal));
+ SetIfCond (D, SymIsRef (SVal, SCOPE_ANY));
NextTok ();
}
}
"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'",
ERR_ILLEGAL_SEG_ATTR,
ERR_ILLEGAL_MACPACK,
ERR_ILLEGAL_FEATURE,
+ ERR_ILLEGAL_SCOPE,
ERR_SYNTAX,
ERR_SYM_ALREADY_DEFINED,
ERR_SYM_UNDEFINED,
/* */
/* */
/* */
-/* (C) 1998-2000 Ullrich von Bassewitz */
+/* (C) 1998-2002 Ullrich von Bassewitz */
/* Wacholderweg 14 */
/* D-70597 Stuttgart */
/* EMail: uz@musoftware.de */
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;
}
NextTok ();
}
} else {
- Result = SymIsRef (SVal);
+ Result = SymIsRef (SVal, SCOPE_ANY);
NextTok ();
}
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));
break;
case TOK_IDENT:
- S = SymRef (SVal);
+ S = SymRef (SVal, SCOPE_LOCAL);
if (SymIsConst (S)) {
/* Use the literal value instead */
N = LiteralExpr (GetSymVal (S));
" .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"
" .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"
" .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"
" .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"
" .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"
" .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"
" .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"
" .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"
}
/* Check if have already a symbol with this name */
- if (SymIsDef (SymName)) {
+ if (SymIsDef (SymName, SCOPE_ANY)) {
AbEnd ("`%s' is already defined", SymName);
}
TOK_BLANK,
TOK_BSS,
TOK_BYTE,
- TOK_CASE,
+ TOK_CASE,
TOK_CHARMAP,
TOK_CODE,
TOK_CONCAT,
-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 */
{
-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;
}
-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;
}
+/*****************************************************************************/
+/* Data */
+/*****************************************************************************/
+
+
+
+/* Scope identifiers */
+#define SCOPE_ANY 0
+#define SCOPE_GLOBAL 1
+#define SCOPE_LOCAL 2
+
+
+
/*****************************************************************************/
/* Code */
/*****************************************************************************/
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);