]> git.sur5r.net Git - cc65/commitdiff
Revised symbol scoping
authorcuz <cuz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Thu, 6 Nov 2003 11:22:31 +0000 (11:22 +0000)
committercuz <cuz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Thu, 6 Nov 2003 11:22:31 +0000 (11:22 +0000)
git-svn-id: svn://svn.cc65.org/cc65/trunk@2614 b7a2c559-68d2-44c3-8de9-860c34a00d81

13 files changed:
src/ca65/condasm.c
src/ca65/expr.c
src/ca65/macpack.c
src/ca65/main.c
src/ca65/make/gcc.mak
src/ca65/make/watcom.mak
src/ca65/pseudo.c
src/ca65/symbol.c [new file with mode: 0644]
src/ca65/symbol.h [new file with mode: 0644]
src/ca65/symentry.c
src/ca65/symentry.h
src/ca65/symtab.c
src/ca65/symtab.h

index 22ff2a8def62069b44cc5b35068e1c576192daf4..70e949852a76cb666738d5bff70a5b16c577e4ad 100644 (file)
@@ -38,6 +38,7 @@
 #include "expr.h"
 #include "instr.h"
 #include "nexttok.h"
+#include "symbol.h"
 #include "symtab.h"
 #include "condasm.h"
 
@@ -304,12 +305,8 @@ void DoConditionals (void)
                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;
@@ -343,12 +340,8 @@ void DoConditionals (void)
                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;
@@ -357,12 +350,8 @@ void DoConditionals (void)
                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;
@@ -407,12 +396,8 @@ void DoConditionals (void)
                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;
index dd0513dd2d31ce2fbf54c7e76f9c5bfc35d3c40b..f72f12eee78cff780be272a9d5a5744c5e10c99f 100644 (file)
@@ -51,9 +51,9 @@
 #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"
@@ -113,7 +113,7 @@ static void FreeExprNode (ExprNode* E)
     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) {
@@ -208,71 +208,11 @@ 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 {
-
-        /* 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));
 }
 
 
@@ -377,20 +317,11 @@ static int FuncMatch (void)
 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));
 }
 
 
@@ -553,34 +484,19 @@ static ExprNode* Factor (void)
                    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:
@@ -977,7 +893,7 @@ ExprNode* GenSymExpr (SymEntry* Sym)
 {
     ExprNode* Expr = NewExprNode (EXPR_SYMBOL);
     Expr->V.Sym = Sym;
-    SymAddRef (Sym, Expr);
+    SymAddExprRef (Sym, Expr);
     return Expr;
 }
 
index e275693224c81da1964cfc7a978c5e4f707c5f82..bb657b26800257ffb67c729bc0a681afbd6b27bb 100644 (file)
@@ -76,7 +76,7 @@ static char MacLongBranch[] =
     "        .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"
@@ -87,7 +87,7 @@ static char MacLongBranch[] =
     "        .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"
@@ -98,7 +98,7 @@ static char MacLongBranch[] =
     "        .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"
@@ -109,7 +109,7 @@ static char MacLongBranch[] =
     "        .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"
@@ -120,7 +120,7 @@ static char MacLongBranch[] =
     "        .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"
@@ -131,7 +131,7 @@ static char MacLongBranch[] =
     "        .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"
@@ -142,7 +142,7 @@ static char MacLongBranch[] =
     "        .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"
@@ -153,7 +153,7 @@ static char MacLongBranch[] =
     "        .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"
index d80f298537f1b9155c7e13e33eefb8926617a80f..fd93fac97b5e1904b017aeeb67e17faa315cecf8 100644 (file)
@@ -139,6 +139,8 @@ static void DefineSymbol (const char* Def)
     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])) {
@@ -177,13 +179,16 @@ static void DefineSymbol (const char* Def)
                }
     }
 
+    /* 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);
 }
 
 
@@ -337,7 +342,6 @@ static void DoPCAssign (void)
 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
@@ -366,8 +370,10 @@ static void OneLine (void)
        } 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
@@ -379,14 +385,14 @@ static void OneLine (void)
                /* 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.
@@ -519,7 +525,7 @@ int main (int argc, char* argv [])
     /* 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;
index ed8d812c31dba134fc51737fe44c17dec2c954c4..b8440d573d7d86289a31810e2d6d1e08676b8ad3 100644 (file)
@@ -39,6 +39,7 @@ OBJS =  anonname.o      \
         segment.o       \
         spool.o         \
         symentry.o      \
+        symbol.o        \
         symtab.o       \
                toklist.o       \
        ulabel.o
index dc0ff3861ca78cb4f4ceec9a16e2ccc1a0190256..195fe866db4e085d51838d0b85af6d07b1e43d74 100644 (file)
@@ -87,6 +87,7 @@ OBJS =        anonname.obj    \
        scanner.obj     \
         segment.obj     \
         spool.obj       \
+       symbol.obj      \
         symentry.obj    \
        symtab.obj      \
        toklist.obj     \
index 641f0417ea25aae69135d440cf192e3e2377e97c..1a98e855dc106493b6d6cb5d943bbe4bb8ba65b5 100644 (file)
@@ -663,11 +663,11 @@ static void DoEnd (void)
 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 ();
     }
 }
 
@@ -1245,11 +1245,12 @@ static void DoProc (void)
 {
     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 {
diff --git a/src/ca65/symbol.c b/src/ca65/symbol.c
new file mode 100644 (file)
index 0000000..ab3e0cc
--- /dev/null
@@ -0,0 +1,113 @@
+/*****************************************************************************/
+/*                                                                           */
+/*                                 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);
+
+        }
+    }
+}
+
+
+
diff --git a/src/ca65/symbol.h b/src/ca65/symbol.h
new file mode 100644 (file)
index 0000000..218806b
--- /dev/null
@@ -0,0 +1,65 @@
+/*****************************************************************************/
+/*                                                                           */
+/*                                 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
+
+
+
index 0dd8130c13b323e9b05a385d26c9c27269a97e10..660fdf0dfca43deeaf2748f158c0dff9b0487ffc 100644 (file)
 #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;
 
 
 
@@ -60,7 +68,23 @@ SymEntry* SymList = 0;       /* List of all symbol table entries */
 
 
 
-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 */
@@ -76,7 +100,7 @@ SymEntry* NewSymEntry (unsigned Name)
     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;
@@ -87,4 +111,234 @@ SymEntry* NewSymEntry (unsigned Name)
 }
 
 
-                   
+
+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;
+}
+
+
+
+
index 189d318547b15b7f52b64c3355452cc5396d917e..5d5aadd0a2073274ccf0778ac1b392f2803f41c4 100644 (file)
 #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 {
@@ -94,37 +103,92 @@ 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 */
index 892cbc56a2b5a9da5ccce95798788bc2064fac7b..70945c34fdff3d3af3eb32c0d9367b79f4ebce39 100644 (file)
 #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 */
 
@@ -101,22 +82,6 @@ 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 */
 {
@@ -129,7 +94,7 @@ static unsigned SymTableSize (unsigned 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 */
@@ -147,7 +112,7 @@ static SymTable* NewSymTable (SymTable* Parent, unsigned Name)
     S->TableSlots   = Slots;
     S->TableEntries = 0;
     S->Parent       = Parent;
-    S->Name         = Name;
+    S->Name         = GetStringId (Name);
     while (Slots--) {
                S->Table[Slots] = 0;
     }
@@ -161,14 +126,15 @@ static SymTable* NewSymTable (SymTable* Parent, unsigned Name)
         } 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 {
@@ -177,13 +143,13 @@ static SymTable* NewSymTable (SymTable* Parent, unsigned Name)
                     }
                 } 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 */
@@ -192,7 +158,7 @@ static SymTable* NewSymTable (SymTable* Parent, unsigned Name)
 
 
 
-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,
@@ -201,8 +167,6 @@ static int SearchSymTree (SymEntry* T, unsigned Name, SymEntry** E)
  * inserted on the right side.
  */
 {
-    int Cmp;
-
     /* Is there a tree? */
     if (T == 0) {
        *E = 0;
@@ -211,17 +175,15 @@ static int SearchSymTree (SymEntry* T, unsigned Name, SymEntry** E)
 
     /* 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 */
@@ -234,12 +196,58 @@ static int SearchSymTree (SymEntry* T, unsigned Name, SymEntry** E)
 
 
 /*****************************************************************************/
-/*                                          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.
@@ -247,18 +255,17 @@ static SymEntry* SymFind (SymTable* Tab, unsigned Name, int AllocNew)
 {
     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;
            }
                }
 
@@ -287,10 +294,10 @@ static SymEntry* SymFind (SymTable* Tab, unsigned Name, int AllocNew)
     } 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) {
@@ -308,14 +315,14 @@ static SymEntry* SymFind (SymTable* Tab, unsigned Name, int AllocNew)
            /* 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;
 
        }
@@ -327,21 +334,24 @@ static SymEntry* SymFind (SymTable* Tab, unsigned Name, int AllocNew)
 
 
 
-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;
@@ -349,114 +359,6 @@ static SymEntry* SymFindAny (SymTable* Tab, unsigned Name)
 
 
 
-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 */
 {
@@ -469,7 +371,7 @@ static void SymImportInternal (const char* Name, unsigned Flags)
     }
 
     /* 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;
@@ -533,7 +435,7 @@ static void SymExportInternal (const char* Name, unsigned Flags)
     }
 
     /* 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);
@@ -586,7 +488,7 @@ static void SymGlobalInternal (const char* Name, unsigned Flags)
     }
 
     /* 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. */
@@ -645,7 +547,7 @@ void SymConDes (const char* Name, unsigned Type, unsigned Prio)
     }
 
     /* 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);
@@ -678,50 +580,6 @@ void SymConDes (const char* Name, unsigned Type, unsigned Prio)
 
 
 
-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 */
 {
@@ -763,7 +621,7 @@ int SymIsZP (SymEntry* S)
        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) {
@@ -777,161 +635,6 @@ int SymIsZP (SymEntry* S)
 
 
 
-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 */
 {
@@ -950,7 +653,7 @@ static void SymCheckUndefined (SymEntry* S)
        /* 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
@@ -1014,7 +717,7 @@ void SymCheck (void)
     SymEntry* S;
 
     /* Check for open lexical levels */
-    if (SymTab->Parent != 0) {
+    if (CurrentScope->Parent != 0) {
        Error (ERR_OPEN_PROC);
     }
 
index b28e7159baeacbe5ede9d309fb8c3e6a6415f5ae..ae343a9c0be138f3837f7ba95c79420f9b506c85 100644 (file)
 #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 */
 
 
 
@@ -78,20 +91,14 @@ void SymEnterLevel (const char* ScopeName);
 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 */
@@ -129,36 +136,6 @@ int SymIsConst (SymEntry* Sym);
 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 */