#include "expr.h"
#include "instr.h"
#include "nexttok.h"
+#include "symbol.h"
#include "symtab.h"
#include "condasm.h"
D = AllocIf (".IFDEF", 1);
NextTok ();
if (IfCond) {
- if (Tok != TOK_IDENT) {
- ErrorSkip (ERR_IDENT_EXPECTED);
- } else {
- SetIfCond (D, SymIsDef (SVal, SCOPE_ANY));
- NextTok ();
- }
+ SymEntry* Sym = ParseScopedSymName (SYM_FIND_EXISTING);
+ SetIfCond (D, Sym != 0 && SymIsDef (Sym));
}
IfCond = GetCurrentIfCond ();
break;
D = AllocIf (".IFNDEF", 1);
NextTok ();
if (IfCond) {
- if (Tok != TOK_IDENT) {
- ErrorSkip (ERR_IDENT_EXPECTED);
- } else {
- SetIfCond (D, !SymIsDef (SVal, SCOPE_ANY));
- NextTok ();
- }
+ SymEntry* Sym = ParseScopedSymName (SYM_FIND_EXISTING);
+ SetIfCond (D, Sym == 0 || !SymIsDef (Sym));
}
IfCond = GetCurrentIfCond ();
break;
D = AllocIf (".IFNREF", 1);
NextTok ();
if (IfCond) {
- if (Tok != TOK_IDENT) {
- ErrorSkip (ERR_IDENT_EXPECTED);
- } else {
- SetIfCond (D, !SymIsRef (SVal, SCOPE_ANY));
- NextTok ();
- }
+ SymEntry* Sym = ParseScopedSymName (SYM_FIND_EXISTING);
+ SetIfCond (D, Sym == 0 || !SymIsRef (Sym));
}
IfCond = GetCurrentIfCond ();
break;
D = AllocIf (".IFREF", 1);
NextTok ();
if (IfCond) {
- if (Tok != TOK_IDENT) {
- ErrorSkip (ERR_IDENT_EXPECTED);
- } else {
- SetIfCond (D, SymIsRef (SVal, SCOPE_ANY));
- NextTok ();
- }
+ SymEntry* Sym = ParseScopedSymName (SYM_FIND_EXISTING);
+ SetIfCond (D, Sym != 0 && SymIsRef (Sym));
}
IfCond = GetCurrentIfCond ();
break;
#include "global.h"
#include "instr.h"
#include "nexttok.h"
-/* #include "objcode.h" */
#include "objfile.h"
#include "segment.h"
+#include "symbol.h"
#include "symtab.h"
#include "toklist.h"
#include "ulabel.h"
if (E) {
if (E->Op == EXPR_SYMBOL) {
/* Remove the symbol reference */
- SymDelRef (E->V.Sym, E);
+ SymDelExprRef (E->V.Sym, E);
}
/* Place the symbol into the free nodes list if possible */
if (FreeNodeCount < MAX_FREE_NODES) {
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 {
-
- /* Any scope */
- Scope = SCOPE_ANY;
-
- }
+ /* Parse the symbol name and search for the symbol */
+ SymEntry* Sym = ParseScopedSymName (SYM_FIND_EXISTING);
- /* Search for the symbol */
- Result = SymIsDef (SVal, Scope);
-
- /* Done */
- return Result;
+ /* Check if the symbol is defined */
+ return (Sym != 0 && SymIsDef (Sym));
}
static int FuncReferenced (void)
/* Handle the .REFERENCED builtin function */
{
- int Result = 0;
-
- if (Tok != TOK_IDENT) {
- Error (ERR_IDENT_EXPECTED);
- if (Tok != TOK_RPAREN) {
- NextTok ();
- }
- } else {
- Result = SymIsRef (SVal, SCOPE_ANY);
- NextTok ();
- }
+ /* Parse the symbol name and search for the symbol */
+ SymEntry* Sym = ParseScopedSymName (SYM_FIND_EXISTING);
- /* Done */
- return Result;
+ /* Check if the symbol is referenced */
+ return (Sym != 0 && SymIsRef (Sym));
}
NextTok ();
break;
- case TOK_NAMESPACE:
- NextTok ();
- if (Tok != TOK_IDENT) {
- Error (ERR_IDENT_EXPECTED);
- N = GenLiteralExpr (0); /* Dummy */
- } else {
- S = SymRef (SVal, SCOPE_GLOBAL);
- if (SymIsConst (S)) {
- /* Use the literal value instead */
- N = GenLiteralExpr (GetSymVal (S));
- } else {
- /* Create symbol node */
- N = GenSymExpr (S);
- }
- NextTok ();
- }
- break;
-
- case TOK_IDENT:
- S = SymRef (SVal, SCOPE_LOCAL);
- if (SymIsConst (S)) {
- /* Use the literal value instead */
- N = GenLiteralExpr (GetSymVal (S));
+ case TOK_NAMESPACE:
+ case TOK_IDENT:
+ /* Search for the symbol */
+ S = ParseScopedSymName (SYM_ALLOC_NEW);
+ if (S == 0) {
+ /* Some weird error happened before */
+ N = GenLiteralExpr (0);
} else {
- /* Create symbol node */
- N = GenSymExpr (S);
+ /* Mark the symbol as referenced */
+ SymRef (S);
+ /* Create symbol node */
+ N = GenSymExpr (S);
}
- NextTok ();
break;
case TOK_ULABEL:
{
ExprNode* Expr = NewExprNode (EXPR_SYMBOL);
Expr->V.Sym = Sym;
- SymAddRef (Sym, Expr);
+ SymAddExprRef (Sym, Expr);
return Expr;
}
" .if .match(Target, 0)\n"
" bne *+5\n"
" jmp Target\n"
- " .elseif .def(Target,local) .and ((*+2)-(Target) <= 127)\n"
+ " .elseif .def(Target) .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,local) .and ((*+2)-(Target) <= 127)\n"
+ " .elseif .def(Target) .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,local) .and ((*+2)-(Target) <= 127)\n"
+ " .elseif .def(Target) .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,local) .and ((*+2)-(Target) <= 127)\n"
+ " .elseif .def(Target) .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,local) .and ((*+2)-(Target) <= 127)\n"
+ " .elseif .def(Target) .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,local) .and ((*+2)-(Target) <= 127)\n"
+ " .elseif .def(Target) .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,local) .and ((*+2)-(Target) <= 127)\n"
+ " .elseif .def(Target) .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,local) .and ((*+2)-(Target) <= 127)\n"
+ " .elseif .def(Target) .and ((*+2)-(Target) <= 127)\n"
" bvc Target\n"
" .else\n"
" bvs *+5\n"
unsigned I;
long Val;
char SymName [MAX_STR_LEN+1];
+ SymEntry* Sym;
+
/* The symbol must start with a character or underline */
if (Def [0] != '_' && !IsAlpha (Def [0])) {
}
}
+ /* Search for the symbol, allocate a new one if it doesn't exist */
+ Sym = SymFind (CurrentScope, SymName, SYM_ALLOC_NEW);
+
/* Check if have already a symbol with this name */
- if (SymIsDef (SymName, SCOPE_ANY)) {
+ if (SymIsDef (Sym)) {
AbEnd ("`%s' is already defined", SymName);
}
- /* Define the symbol */
- SymDef (SymName, GenLiteralExpr (Val), SYM_DEFAULT);
+ /* Mark the symbol as defined */
+ SymDef (Sym, GenLiteralExpr (Val), SYM_DEFAULT);
}
static void OneLine (void)
/* Assemble one line */
{
- char Ident [MAX_STR_LEN+1];
int Done = 0;
/* Initialize the new listing line if we are actually reading from file
} else {
/* No, label. Remember the identifier, then skip it */
- int HadWS = WS; /* Did we have whitespace before the ident? */
- strcpy (Ident, SVal);
+ int HadWS = WS; /* Did we have whitespace before the ident? */
+
+ /* Generate the symbol table entry, then skip the name */
+ SymEntry* Sym = SymFind (CurrentScope, SVal, SYM_ALLOC_NEW);
NextTok ();
/* If a colon follows, this is a label definition. If there
/* Skip the '=' */
NextTok ();
/* Define the symbol with the expression following the '=' */
- SymDef (Ident, Expression(), Flags);
+ SymDef (Sym, Expression(), Flags);
/* Don't allow anything after a symbol definition */
Done = 1;
} else {
/* Define the symbol flags */
unsigned Flags = IsZPSeg ()? SYM_ZP | SYM_LABEL : SYM_LABEL;
/* Define a label */
- SymDef (Ident, GenCurrentPC (), Flags);
+ SymDef (Sym, GenCurrentPC (), Flags);
/* Skip the colon. If NoColonLabels is enabled, allow labels
* without a colon if there is no whitespace before the
* identifier.
/* Enter the base lexical level. We must do that here, since we may
* define symbols using -D.
*/
- SymEnterLevel (0);
+ SymEnterLevel ("");
/* Check the parameters */
I = 1;
segment.o \
spool.o \
symentry.o \
+ symbol.o \
symtab.o \
toklist.o \
ulabel.o
scanner.obj \
segment.obj \
spool.obj \
+ symbol.obj \
symentry.obj \
symtab.obj \
toklist.obj \
static void DoEndProc (void)
/* Leave a lexical level */
{
- if (!SymIsLocalLevel ()) {
+ if (CurrentScope != RootScope) {
+ SymLeaveLevel ();
+ } else {
/* No local scope */
ErrorSkip (ERR_NO_OPEN_PROC);
- } else {
- SymLeaveLevel ();
}
}
{
if (Tok == TOK_IDENT) {
/* The new scope has a name */
+ SymEntry* Sym = SymFind (CurrentScope, SVal, SYM_ALLOC_NEW);
unsigned Flags = SYM_LABEL;
if (IsZPSeg ()) {
Flags |= SYM_ZP;
}
- SymDef (SVal, GenCurrentPC (), Flags);
+ SymDef (Sym, GenCurrentPC (), Flags);
SymEnterLevel (SVal);
NextTok ();
} else {
--- /dev/null
+/*****************************************************************************/
+/* */
+/* symbol.c */
+/* */
+/* Parse a symbol name and search for it */
+/* */
+/* */
+/* */
+/* (C) 1998-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 <string.h>
+
+/* ca65 */
+#include "error.h"
+#include "nexttok.h"
+#include "scanner.h"
+#include "symbol.h"
+#include "symtab.h"
+
+
+
+/*****************************************************************************/
+/* Data */
+/*****************************************************************************/
+
+
+
+/*****************************************************************************/
+/* Code */
+/*****************************************************************************/
+
+
+
+SymEntry* ParseScopedSymName (int AllocNew)
+/* Parse a (possibly scoped) symbol name, search for it in the symbol table
+ * and return the symbol table entry.
+ */
+{
+ /* Get the starting table */
+ SymTable* Scope;
+ if (Tok == TOK_NAMESPACE) {
+ Scope = RootScope;
+ NextTok ();
+ } else {
+ Scope = CurrentScope;
+ }
+
+ /* Resolve scopes */
+ while (1) {
+
+ /* An identifier must follow. Remember and skip it. */
+ char Name[sizeof (SVal)];
+ if (Tok != TOK_IDENT) {
+ Error (ERR_IDENT_EXPECTED);
+ return 0;
+ }
+ strcpy (Name, SVal);
+ NextTok ();
+
+ /* If the next token is a namespace token, handle the name as the
+ * name of a scope, otherwise it's the name of a symbol in that
+ * scope.
+ */
+
+ if (Tok == TOK_NAMESPACE) {
+
+ /* Search for the child scope */
+ Scope = SymFindScope (Scope, Name, AllocNew);
+
+ /* Skip the namespace token */
+ NextTok ();
+
+ /* If we didn't find the scope, bail out */
+ if (Scope == 0) {
+ return 0;
+ }
+
+ } else {
+
+ /* Search for the symbol and return it */
+ return SymFind (Scope, Name, AllocNew);
+
+ }
+ }
+}
+
+
+
--- /dev/null
+/*****************************************************************************/
+/* */
+/* symbol.h */
+/* */
+/* Parse a symbol name and search for it */
+/* */
+/* */
+/* */
+/* (C) 1998-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 SYMBOL_H
+#define SYMBOL_H
+
+
+
+/*****************************************************************************/
+/* Data */
+/*****************************************************************************/
+
+
+
+/*****************************************************************************/
+/* Code */
+/*****************************************************************************/
+
+
+
+struct SymEntry* ParseScopedSymName (int AllowNew);
+/* Parse a (possibly scoped) symbol name, search for it in the symbol table
+ * and return the symbol table entry.
+ */
+
+
+
+/* End of symbol.h */
+
+#endif
+
+
+
#include "xmalloc.h"
/* ca65 */
+#include "error.h"
+#include "expr.h"
+#include "global.h"
#include "scanner.h"
+#include "spool.h"
#include "symentry.h"
-SymEntry* SymList = 0; /* List of all symbol table entries */
+/* List of all symbol table entries */
+SymEntry* SymList = 0;
+
+/* Pointer to last defined symbol */
+SymEntry* SymLast = 0;
-SymEntry* NewSymEntry (unsigned Name)
+int IsLocalName (const char* Name)
+/* Return true if Name is the name of a local symbol */
+{
+ return (*Name == LocalStart);
+}
+
+
+
+int IsLocalNameId (unsigned Name)
+/* Return true if Name is the name of a local symbol */
+{
+ return (*GetString (Name) == LocalStart);
+}
+
+
+
+SymEntry* NewSymEntry (const char* Name)
/* Allocate a symbol table entry, initialize and return it */
{
/* Allocate memory */
S->V.Expr = 0;
S->ExprRefs = AUTO_COLLECTION_INITIALIZER;
memset (S->ConDesPrio, 0, sizeof (S->ConDesPrio));
- S->Name = Name;
+ S->Name = GetStringId (Name);
/* Insert it into the list of all entries */
S->List = SymList;
}
-
+
+void SymRef (SymEntry* S)
+/* Mark the given symbol as referenced */
+{
+ /* Mark the symbol as referenced */
+ S->Flags |= SF_REFERENCED;
+}
+
+
+
+void SymDef (SymEntry* S, ExprNode* Expr, unsigned Flags)
+/* Define a new symbol */
+{
+ if (S->Flags & SF_IMPORT) {
+ /* Defined symbol is marked as imported external symbol */
+ Error (ERR_SYM_ALREADY_IMPORT, GetSymName (S));
+ return;
+ }
+ if (S->Flags & SF_DEFINED) {
+ /* Multiple definition */
+ Error (ERR_SYM_ALREADY_DEFINED, GetSymName (S));
+ S->Flags |= SF_MULTDEF;
+ return;
+ }
+
+ /* Set the symbol data */
+ 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->Flags |= SF_DEFINED;
+ if (Flags & SYM_ZP) {
+ S->Flags |= SF_ZP;
+ }
+ if (Flags & SYM_LABEL) {
+ S->Flags |= SF_LABEL;
+ }
+
+ /* If the symbol is a ZP symbol, check if the value is in correct range */
+ if (S->Flags & SF_ZP) {
+ /* Already marked as ZP symbol by some means */
+ if (!IsByteExpr (Expr)) {
+ Error (ERR_RANGE);
+ }
+ }
+
+ /* If this is not a local symbol, remember it as the last global one */
+ if (!IsLocalNameId (S->Name)) {
+ SymLast = S;
+ }
+}
+
+
+
+int SymIsDef (const SymEntry* S)
+/* Return true if the given symbol is already defined */
+{
+ return (S->Flags & SF_DEFINED) != 0;
+}
+
+
+
+int SymIsRef (const SymEntry* S)
+/* Return true if the given symbol has been referenced */
+{
+ return (S->Flags & SF_REFERENCED) != 0;
+}
+
+
+
+int SymIsImport (const SymEntry* S)
+/* Return true if the given symbol is marked as import */
+{
+ /* Resolve trampoline entries */
+ if (S->Flags & SF_TRAMPOLINE) {
+ S = S->V.Sym;
+ }
+
+ /* Check the import flag */
+ return (S->Flags & SF_IMPORT) != 0;
+}
+
+
+
+int SymHasExpr (const SymEntry* S)
+/* Return true if the given symbol has an associated expression */
+{
+ /* Resolve trampoline entries */
+ if (S->Flags & SF_TRAMPOLINE) {
+ S = S->V.Sym;
+ }
+
+ /* 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;
+ }
+}
+
+
+
+void SymMarkUser (SymEntry* S)
+/* Set a user mark on the specified symbol */
+{
+ /* Resolve trampoline entries */
+ if (S->Flags & SF_TRAMPOLINE) {
+ S = S->V.Sym;
+ }
+
+ /* Set the bit */
+ S->Flags |= SF_USER;
+}
+
+
+
+void SymUnmarkUser (SymEntry* S)
+/* Remove a user mark from the specified symbol */
+{
+ /* Resolve trampoline entries */
+ if (S->Flags & SF_TRAMPOLINE) {
+ S = S->V.Sym;
+ }
+
+ /* Reset the bit */
+ S->Flags &= ~SF_USER;
+}
+
+
+
+int SymHasUserMark (SymEntry* S)
+/* Return the state of the user mark for the specified symbol */
+{
+ /* Resolve trampoline entries */
+ if (S->Flags & SF_TRAMPOLINE) {
+ S = S->V.Sym;
+ }
+
+ /* Check the bit */
+ return (S->Flags & SF_USER) != 0;
+}
+
+
+
+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 */
+{
+ /* Resolve trampoline entries */
+ if (S->Flags & SF_TRAMPOLINE) {
+ S = S->V.Sym;
+ }
+
+ PRECONDITION (S != 0 && (S->Flags & SF_CONST) == 0);
+ return S->V.Expr;
+}
+
+
+
+const char* GetSymName (SymEntry* S)
+/* Return the name of the symbol */
+{
+ /* Resolve trampoline entries */
+ if (S->Flags & SF_TRAMPOLINE) {
+ S = S->V.Sym;
+ }
+ return GetString (S->Name);
+}
+
+
+
+unsigned GetSymIndex (SymEntry* S)
+/* Return the symbol index for the given symbol */
+{
+ /* Resolve trampoline entries */
+ if (S->Flags & SF_TRAMPOLINE) {
+ S = S->V.Sym;
+ }
+ PRECONDITION (S != 0 && (S->Flags & SF_INDEXED));
+ return S->Index;
+}
+
+
+
+const FilePos* GetSymPos (SymEntry* S)
+/* Return the position of first occurence in the source for the given symbol */
+{
+ /* Resolve trampoline entries */
+ if (S->Flags & SF_TRAMPOLINE) {
+ S = S->V.Sym;
+ }
+ PRECONDITION (S != 0);
+ return &S->Pos;
+}
+
+
+
+
#define SF_DEFINED 0x4000 /* Defined */
#define SF_REFERENCED 0x8000 /* Referenced */
+/* Flags used in SymDef */
+#define SYM_DEFAULT 0x00
+#define SYM_ZP 0x01
+#define SYM_LABEL 0x02
+
+/* Arguments for SymFind... */
+#define SYM_FIND_EXISTING 0
+#define SYM_ALLOC_NEW 1
+
/* Structure of a symbol table entry */
typedef struct SymEntry SymEntry;
struct SymEntry {
/* List of all symbol table entries */
extern SymEntry* SymList;
+/* Pointer to last defined symbol */
+extern SymEntry* SymLast;
+
/*****************************************************************************/
-/* Code */
+/* Code */
/*****************************************************************************/
-SymEntry* NewSymEntry (unsigned Name);
+int IsLocalName (const char* Name);
+/* Return true if Name is the name of a local symbol */
+
+int IsLocalNameId (unsigned Name);
+/* Return true if Name is the name of a local symbol */
+
+SymEntry* NewSymEntry (const char* Name);
/* 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 */
+INLINE void SymAddExprRef (SymEntry* Sym, struct ExprNode* Expr)
+/* Add an expression reference to this symbol */
{
CollAppend (&Sym->ExprRefs, Expr);
}
#else
-#define SymAddRef(Sym,Expr) CollAppend (&(Sym)->ExprRefs, Expr)
+#define SymAddExprRef(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 */
+INLINE void SymDelExprRef (SymEntry* Sym, struct ExprNode* Expr)
+/* Delete an expression reference to this symbol */
{
CollDeleteItem (&Sym->ExprRefs, Expr);
}
#else
-#define SymDelRef(Sym,Expr) CollDeleteItem (&(Sym)->ExprRefs, Expr)
+#define SymDelExprRef(Sym,Expr) CollDeleteItem (&(Sym)->ExprRefs, Expr)
#endif
+void SymDef (SymEntry* Sym, ExprNode* Expr, unsigned Flags);
+/* Mark a symbol as defined */
+
+void SymRef (SymEntry* Sym);
+/* Mark the given symbol as referenced */
+
+int SymIsDef (const SymEntry* Sym);
+/* Return true if the given symbol is already defined */
+
+int SymIsRef (const SymEntry* Sym);
+/* Return true if the given symbol has been referenced */
+
+int SymIsImport (const SymEntry* Sym);
+/* Return true if the given symbol is marked as import */
+
+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 */
+
+void SymUnmarkUser (SymEntry* Sym);
+/* Remove a user mark from the specified symbol */
+
+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 char* GetSymName (SymEntry* Sym);
+/* Return the name of the symbol */
+
+unsigned GetSymIndex (SymEntry* Sym);
+/* Return the symbol index for the given symbol */
+
+const FilePos* GetSymPos (SymEntry* Sym);
+/* Return the position of first occurence in the source for the given symbol */
+
+
/* End of symentry.h */
#define SF_DBGINFOMASK (SF_TRAMPOLINE | SF_DEFINED | SF_EXPORT | SF_IMPORT)
#define SF_DBGINFOVAL (SF_DEFINED)
-/* Definitions for the hash table */
-#define MAIN_HASHTAB_SIZE 213
-#define SUB_HASHTAB_SIZE 53
-typedef struct SymTable 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 TableEntries; /* Number of entries in the table */
- unsigned Name; /* Name of the scope */
- SymEntry* Table [1]; /* Dynamic allocation */
-};
-
-/* Arguments for SymFind */
-#define SF_FIND_EXISTING 0
-#define SF_ALLOC_NEW 1
+/* Symbol tables */
+SymTable* CurrentScope = 0; /* Pointer to current symbol table */
+SymTable* RootScope = 0; /* Root symbol table */
/* Symbol table variables */
-static SymEntry* SymLast = 0; /* Pointer to last defined symbol */
-static SymTable* SymTab = 0; /* Pointer to current symbol table */
-static SymTable* RootTab = 0; /* Root symbol table */
static unsigned ImportCount = 0;/* Counter for import symbols */
static unsigned ExportCount = 0;/* Counter for export symbols */
-static int IsLocalName (const char* Name)
-/* Return true if Name is the name of a local symbol */
-{
- return (*Name == LocalStart);
-}
-
-
-
-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 */
{
-static SymTable* NewSymTable (SymTable* Parent, unsigned Name)
+static SymTable* NewSymTable (SymTable* Parent, const char* Name)
/* Allocate a symbol table on the heap and return it */
{
/* Determine the lexical level and the number of table slots */
S->TableSlots = Slots;
S->TableEntries = 0;
S->Parent = Parent;
- S->Name = Name;
+ S->Name = GetStringId (Name);
while (Slots--) {
S->Table[Slots] = 0;
}
} else {
while (1) {
/* Choose next entry */
- if (S->Name < T->Name) {
+ int Cmp = strcmp (Name, GetString (T->Name));
+ if (Cmp < 0) {
if (T->Left) {
T = T->Left;
} else {
T->Left = S;
break;
}
- } else if (S->Name > T->Name) {
+ } else if (Cmp > 0) {
if (T->Right) {
T = T->Right;
} else {
}
} else {
/* Duplicate scope name */
- Internal ("Duplicate scope name: `%s'", GetString (S->Name));
+ Internal ("Duplicate scope name: `%s'", Name);
}
}
}
} else {
/* This is the root table */
- RootTab = S;
+ RootScope = S;
}
/* Return the prepared struct */
-static int SearchSymTree (SymEntry* T, unsigned Name, SymEntry** E)
+static int SearchSymTree (SymEntry* T, const char* Name, SymEntry** E)
/* Search in the given tree for a name. If we find the symbol, the function
* will return 0 and put the entry pointer into E. If we did not find the
* symbol, and the tree is empty, E is set to NULL. If the tree is not empty,
* inserted on the right side.
*/
{
- int Cmp;
-
/* Is there a tree? */
if (T == 0) {
*E = 0;
/* We have a table, search it */
while (1) {
+
+ /* Get the symbol name */
+ const char* SymName = GetString (T->Name);
+
/* Choose next entry */
- if (Name < T->Name) {
- Cmp = -1;
- } else if (Name > T->Name) {
- Cmp = +1;
- } else {
- Cmp = 0;
- }
- if (Name < T->Name && T->Left) {
+ int Cmp = strcmp (Name, SymName);
+ if (Cmp < 0 && T->Left) {
T = T->Left;
- } else if (Name > T->Name && T->Right) {
+ } else if (Cmp > 0&& T->Right) {
T = T->Right;
} else {
/* Found or end of search, return the result */
/*****************************************************************************/
-/* Code */
+/* Code */
/*****************************************************************************/
-static SymEntry* SymFind (SymTable* Tab, unsigned Name, int AllocNew)
+void SymEnterLevel (const char* ScopeName)
+/* Enter a new lexical level */
+{
+ /* ### Check existing scope */
+
+ /* Create the new table */
+ CurrentScope = NewSymTable (CurrentScope, ScopeName);
+}
+
+
+
+void SymLeaveLevel (void)
+/* Leave the current lexical level */
+{
+ CurrentScope = CurrentScope->Parent;
+}
+
+
+
+SymTable* SymFindScope (SymTable* Parent, const char* Name, unsigned Flags)
+/* Find a scope in the given enclosing scope */
+{
+ SymTable** T = &Parent->Childs;
+ while (*T) {
+ int Cmp = strcmp (Name, GetString ((*T)->Name));
+ if (Cmp < 0) {
+ T = &(*T)->Left;
+ } else if (Cmp > 0) {
+ T = &(*T)->Right;
+ } else {
+ /* Found the scope */
+ return *T;
+ }
+ }
+
+ /* Create a new scope if requested and we didn't find one */
+ if (*T == 0 && Flags == SYM_ALLOC_NEW) {
+ *T = NewSymTable (Parent, Name);
+ }
+
+ /* Return the scope */
+ return *T;
+}
+
+
+
+SymEntry* SymFind (SymTable* Scope, const char* Name, int AllocNew)
/* 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
* new entry created, or - in case AllocNew is zero - return 0.
{
SymEntry* S;
int Cmp;
- unsigned Hash;
- if (IsLocalNameId (Name)) {
+ if (IsLocalName (Name)) {
/* Local symbol, get the table */
if (!SymLast) {
/* No last global, so there's no local table */
Error (ERR_ILLEGAL_LOCAL_USE);
if (AllocNew) {
- return NewSymEntry (Name);
+ return NewSymEntry (Name);
} else {
- return 0;
+ return 0;
}
}
} else {
/* Global symbol: Get the hash value for the name */
- Hash = Name % Tab->TableSlots;
+ unsigned Hash = HashStr (Name) % Scope->TableSlots;
/* Search for the entry */
- Cmp = SearchSymTree (Tab->Table[Hash], Name, &S);
+ Cmp = SearchSymTree (Scope->Table[Hash], Name, &S);
/* If we found an entry, return it */
if (Cmp == 0) {
/* Otherwise create a new entry, insert and return it */
SymEntry* N = NewSymEntry (Name);
if (S == 0) {
- Tab->Table[Hash] = N;
+ Scope->Table[Hash] = N;
} else if (Cmp < 0) {
S->Left = N;
} else {
S->Right = N;
}
- N->SymTab = Tab;
- ++Tab->TableEntries;
+ N->SymTab = Scope;
+ ++Scope->TableEntries;
return N;
}
-static SymEntry* SymFindAny (SymTable* Tab, unsigned Name)
-/* Find a symbol in any table */
+static SymEntry* SymFindAny (SymTable* Scope, const char* Name)
+/* Find a symbol in the given or any of its parent scopes. The function will
+ * never create a new symbol, since this can only be done in one specific
+ * scope.
+ */
{
SymEntry* Sym;
do {
/* Search in the current table */
- Sym = SymFind (Tab, Name, SF_FIND_EXISTING);
+ Sym = SymFind (Scope, Name, SYM_FIND_EXISTING);
if (Sym) {
/* Found, return it */
return Sym;
} else {
/* Not found, search in the parent scope, if we have one */
- Tab = Tab->Parent;
+ Scope = Scope->Parent;
}
- } while (Sym == 0 && Tab != 0);
+ } while (Sym == 0 && Scope != 0);
/* Not found */
return 0;
-void SymEnterLevel (const char* ScopeName)
-/* Enter a new lexical level */
-{
- /* Accept NULL pointers for the scope name */
- if (ScopeName == 0) {
- ScopeName = "";
- }
-
- /* Create the new table */
- SymTab = NewSymTable (SymTab, GetStringId (ScopeName));
-}
-
-
-
-void SymLeaveLevel (void)
-/* Leave the current lexical level */
-{
- SymTab = SymTab->Parent;
-}
-
-
-
-int SymIsLocalLevel (void)
-/* Return true if we are on a local symbol table level. */
-{
- return (SymTab != RootTab);
-}
-
-
-
-void SymDef (const char* Name, ExprNode* Expr, unsigned Flags)
-/* Define a new symbol */
-{
- /* Do we have such a symbol? */
- SymEntry* S = SymFind (SymTab, GetStringId (Name), SF_ALLOC_NEW);
- if (S->Flags & SF_IMPORT) {
- /* Defined symbol is marked as imported external symbol */
- Error (ERR_SYM_ALREADY_IMPORT, Name);
- return;
- }
- if (S->Flags & SF_DEFINED) {
- /* Multiple definition */
- Error (ERR_SYM_ALREADY_DEFINED, Name);
- S->Flags |= SF_MULTDEF;
- return;
- }
-
- /* Set the symbol data */
- 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->Flags |= SF_DEFINED;
- if (Flags & SYM_ZP) {
- S->Flags |= SF_ZP;
- }
- if (Flags & SYM_LABEL) {
- S->Flags |= SF_LABEL;
- }
-
- /* If the symbol is a ZP symbol, check if the value is in correct range */
- if (S->Flags & SF_ZP) {
- /* Already marked as ZP symbol by some means */
- if (!IsByteExpr (Expr)) {
- Error (ERR_RANGE);
- }
- }
-
- /* If this is not a local symbol, remember it as the last global one */
- if (!IsLocalName (Name)) {
- SymLast = S;
- }
-}
-
-
-
-SymEntry* SymRef (const char* Name, int Scope)
-/* Search for the symbol and return it */
-{
- SymEntry* S;
- unsigned NameId = GetStringId (Name);
-
- switch (Scope) {
- case SCOPE_GLOBAL: S = SymFind (RootTab, NameId, SF_ALLOC_NEW); break;
- case SCOPE_LOCAL: S = SymFind (SymTab, NameId, SF_ALLOC_NEW); break;
-
- /* Others are not allowed */
- case SCOPE_ANY:
- default:
- Internal ("Invalid scope in SymRef: %d", Scope);
- /* NOTREACHED */
- S = 0;
- }
-
- /* Mark the symbol as referenced */
- S->Flags |= SF_REFERENCED;
-
- /* Return it */
- return S;
-}
-
-
-
static void SymImportInternal (const char* Name, unsigned Flags)
/* Mark the given symbol as an imported symbol */
{
}
/* Do we have such a symbol? */
- S = SymFind (SymTab, GetStringId (Name), SF_ALLOC_NEW);
+ S = SymFind (CurrentScope, Name, SYM_ALLOC_NEW);
if (S->Flags & SF_DEFINED) {
Error (ERR_SYM_ALREADY_DEFINED, Name);
S->Flags |= SF_MULTDEF;
}
/* Do we have such a symbol? */
- S = SymFind (SymTab, GetStringId (Name), SF_ALLOC_NEW);
+ S = SymFind (CurrentScope, Name, SYM_ALLOC_NEW);
if (S->Flags & SF_IMPORT) {
/* The symbol is already marked as imported external symbol */
Error (ERR_SYM_ALREADY_IMPORT, Name);
}
/* Search for this symbol, create a new entry if needed */
- S = SymFind (SymTab, GetStringId (Name), SF_ALLOC_NEW);
+ S = SymFind (CurrentScope, Name, SYM_ALLOC_NEW);
/* If the symbol is already marked as import or export, check the
* size of the definition, then bail out. */
}
/* Do we have such a symbol? */
- S = SymFind (SymTab, GetStringId (Name), SF_ALLOC_NEW);
+ S = SymFind (CurrentScope, Name, SYM_ALLOC_NEW);
if (S->Flags & SF_IMPORT) {
/* The symbol is already marked as imported external symbol */
Error (ERR_SYM_ALREADY_IMPORT, Name);
-int SymIsDef (const char* Name, int Scope)
-/* Return true if the given symbol is already defined */
-{
- SymEntry* S = 0;
-
- /* Get the string pool index for the name */
- unsigned NameId = GetStringId (Name);
-
- /* Search for the symbol */
- switch (Scope) {
- case SCOPE_ANY: S = SymFindAny (SymTab, NameId); break;
- case SCOPE_GLOBAL: S = SymFind (RootTab, NameId, SF_FIND_EXISTING); break;
- case SCOPE_LOCAL: S = SymFind (SymTab, NameId, 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 Scope)
-/* Return true if the given symbol has been referenced */
-{
- SymEntry* S = 0;
-
- /* Get the string pool index for the name */
- unsigned NameId = GetStringId (Name);
-
- /* Search for the symbol */
- switch (Scope) {
- case SCOPE_ANY: S = SymFindAny (SymTab, NameId); break;
- case SCOPE_GLOBAL: S = SymFind (RootTab, NameId, SF_FIND_EXISTING); break;
- case SCOPE_LOCAL: S = SymFind (SymTab, NameId, 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;
-}
-
-
-
int SymIsConst (SymEntry* S)
/* Return true if the given symbol has a constant value */
{
S->SymTab->Parent != 0) {
/* Try to find a symbol with the same name in the enclosing scope */
- SymEntry* E = SymFindAny (S->SymTab->Parent, S->Name);
+ SymEntry* E = SymFindAny (S->SymTab->Parent, GetString (S->Name));
/* If we found one, use the ZP flag */
if (E && (E->Flags & SF_ZP) != 0) {
-int SymIsImport (SymEntry* S)
-/* Return true if the given symbol is marked as import */
-{
- /* Resolve trampoline entries */
- if (S->Flags & SF_TRAMPOLINE) {
- S = S->V.Sym;
- }
-
- /* Check the import flag */
- return (S->Flags & SF_IMPORT) != 0;
-}
-
-
-
-int SymHasExpr (SymEntry* S)
-/* Return true if the given symbol has an associated expression */
-{
- /* Resolve trampoline entries */
- if (S->Flags & SF_TRAMPOLINE) {
- S = S->V.Sym;
- }
-
- /* 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;
- }
-}
-
-
-
-void SymMarkUser (SymEntry* S)
-/* Set a user mark on the specified symbol */
-{
- /* Resolve trampoline entries */
- if (S->Flags & SF_TRAMPOLINE) {
- S = S->V.Sym;
- }
-
- /* Set the bit */
- S->Flags |= SF_USER;
-}
-
-
-
-void SymUnmarkUser (SymEntry* S)
-/* Remove a user mark from the specified symbol */
-{
- /* Resolve trampoline entries */
- if (S->Flags & SF_TRAMPOLINE) {
- S = S->V.Sym;
- }
-
- /* Reset the bit */
- S->Flags &= ~SF_USER;
-}
-
-
-
-int SymHasUserMark (SymEntry* S)
-/* Return the state of the user mark for the specified symbol */
-{
- /* Resolve trampoline entries */
- if (S->Flags & SF_TRAMPOLINE) {
- S = S->V.Sym;
- }
-
- /* Check the bit */
- return (S->Flags & SF_USER) != 0;
-}
-
-
-
-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;
-}
-
-
-
-ExprNode* GetSymExpr (SymEntry* S)
-/* Get the expression for a non-const symbol */
-{
- /* Resolve trampoline entries */
- if (S->Flags & SF_TRAMPOLINE) {
- S = S->V.Sym;
- }
-
- PRECONDITION (S != 0 && (S->Flags & SF_CONST) == 0);
- return S->V.Expr;
-}
-
-
-
-const char* GetSymName (SymEntry* S)
-/* Return the name of the symbol */
-{
- /* Resolve trampoline entries */
- if (S->Flags & SF_TRAMPOLINE) {
- S = S->V.Sym;
- }
- return GetString (S->Name);
-}
-
-
-
-unsigned GetSymIndex (SymEntry* S)
-/* Return the symbol index for the given symbol */
-{
- /* Resolve trampoline entries */
- if (S->Flags & SF_TRAMPOLINE) {
- S = S->V.Sym;
- }
- PRECONDITION (S != 0 && (S->Flags & SF_INDEXED));
- return S->Index;
-}
-
-
-
-const FilePos* GetSymPos (SymEntry* S)
-/* Return the position of first occurence in the source for the given symbol */
-{
- /* Resolve trampoline entries */
- if (S->Flags & SF_TRAMPOLINE) {
- S = S->V.Sym;
- }
- PRECONDITION (S != 0);
- return &S->Pos;
-}
-
-
-
static void SymCheckUndefined (SymEntry* S)
/* Handle an undefined symbol */
{
/* It's a global symbol, get the higher level table */
SymTable* Tab = S->SymTab->Parent;
while (Tab) {
- Sym = SymFindAny (Tab, S->Name);
+ Sym = SymFindAny (Tab, GetString (S->Name));
if (Sym) {
if (Sym->Flags & (SF_DEFINED | SF_IMPORT)) {
/* We've found a symbol in a higher level that is
SymEntry* S;
/* Check for open lexical levels */
- if (SymTab->Parent != 0) {
+ if (CurrentScope->Parent != 0) {
Error (ERR_OPEN_PROC);
}
#define SCOPE_GLOBAL 1
#define SCOPE_LOCAL 2
-/* Flags used in SymDef */
-#define SYM_DEFAULT 0x00
-#define SYM_ZP 0x01
-#define SYM_LABEL 0x02
+/* A symbol table */
+typedef struct SymTable 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 TableEntries; /* Number of entries in the table */
+ unsigned Name; /* Name of the scope */
+ SymEntry* Table[1]; /* Dynamic allocation */
+};
+
+/* Symbol tables */
+SymTable* CurrentScope; /* Pointer to current symbol table */
+SymTable* RootScope; /* Root symbol table */
void SymLeaveLevel (void);
/* Leave the current lexical level */
-int SymIsLocalLevel (void);
-/* Return true if we are on a local symbol table level. */
+SymTable* SymFindScope (SymTable* Parent, const char* Name, unsigned Flags);
+/* Find a scope in the given enclosing scope */
-void SymDef (const char* Name, ExprNode* Expr, unsigned Flags);
-/* Define a new symbol */
-
-SymEntry* SymRef (const char* Name, int Scope);
-/* Search for the symbol and return it */
-
-int SymIsDef (const char* Name, int Scope);
-/* Return true if the given symbol is already defined */
-
-int SymIsRef (const char* Name, int Scope);
-/* Return true if the given symbol has been referenced */
+SymEntry* SymFind (SymTable* Scope, const char* Name, int AllocNew);
+/* 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
+ * new entry created, or - in case AllocNew is zero - return 0.
+ */
void SymImport (const char* Name);
/* Mark the given symbol as an imported symbol */
int SymIsZP (SymEntry* Sym);
/* Return true if the symbol is explicitly marked as zeropage symbol */
-int SymIsImport (SymEntry* Sym);
-/* Return true if the given symbol is marked as import */
-
-int SymHasExpr (SymEntry* Sym);
-/* Return true if the given symbol has an associated expression */
-
-void SymMarkUser (SymEntry* Sym);
-/* Set a user mark on the specified symbol */
-
-void SymUnmarkUser (SymEntry* Sym);
-/* Remove a user mark from the specified symbol */
-
-int SymHasUserMark (SymEntry* Sym);
-/* Return the state of the user mark for the specified symbol */
-
-long GetSymVal (SymEntry* Sym);
-/* Return the symbol value */
-
-ExprNode* GetSymExpr (SymEntry* Sym);
-/* Get the expression for a non-const symbol */
-
-const char* GetSymName (SymEntry* Sym);
-/* Return the name of the symbol */
-
-unsigned GetSymIndex (SymEntry* Sym);
-/* Return the symbol index for the given symbol */
-
-const FilePos* GetSymPos (SymEntry* Sym);
-/* Return the position of first occurence in the source for the given symbol */
-
void SymCheck (void);
/* Run through all symbols and check for anomalies and errors */