]> git.sur5r.net Git - cc65/blobdiff - src/ca65/symbol.c
Fixed _textcolor definition.
[cc65] / src / ca65 / symbol.c
index 15c081e87abf0a2253d5dd8b451123a73f0d866a..3b06fd1a2bdac3910bdbcd5ce7108da06176851a 100644 (file)
@@ -6,10 +6,10 @@
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
-/* (C) 1998-2003 Ullrich von Bassewitz                                       */
-/*               Römerstraße 52                                              */
-/*               D-70794 Filderstadt                                         */
-/* EMail:        uz@cc65.org                                                 */
+/* (C) 1998-2012, Ullrich von Bassewitz                                      */
+/*                Roemerstrasse 52                                           */
+/*                D-70794 Filderstadt                                        */
+/* EMail:         uz@cc65.org                                                */
 /*                                                                           */
 /*                                                                           */
 /* This software is provided 'as-is', without any expressed or implied       */
 #include "nexttok.h"
 #include "scanner.h"
 #include "symbol.h"
-#include "symtab.h"
 
 
 
 /*****************************************************************************/
-/*                                          Code                                    */
+/*                                   Code                                    */
 /*****************************************************************************/
 
 
 
-SymTable* ParseScopedIdent (char* Name, StrBuf* ScopeName)
-/* Parse a (possibly scoped) identifer. Name must point to a buffer big enough
- * to hold such an identifier. The scope of the name must exist and is returned
- * as function result, while the last part (the identifier) which may be either
- * a symbol or a scope depending on the context is returned in Name. ScopeName
- * is a string buffer that is used to store the name of the scope, the
- * identifier lives in. It does contain anything but the identifier itself, so
- * if ScopeName is empty on return, no explicit scope was specified. The full
- * name of the identifier (including the scope) is ScopeName+Name.
- */
+SymTable* ParseScopedIdent (StrBuf* Name, StrBuf* FullName)
+/* Parse a (possibly scoped) identifer. The scope of the name must exist and
+** is returned as function result, while the last part (the identifier) which
+** may be either a symbol or a scope depending on the context is returned in
+** Name. FullName is a string buffer that is used to store the full name of
+** the identifier including the scope. It is used internally and may be used
+** by the caller for error messages or similar.
+*/
 {
-    /* Get the starting table */
     SymTable* Scope;
-    if (Tok == TOK_NAMESPACE) {
+
+    /* Clear both passed string buffers */
+    SB_Clear (Name);
+    SB_Clear (FullName);
+
+    /* Get the starting table */
+    if (CurTok.Tok == TOK_NAMESPACE) {
 
         /* Start from the root scope */
         Scope = RootScope;
 
-    } else if (Tok == TOK_IDENT) {
+    } else if (CurTok.Tok == TOK_IDENT) {
 
         /* Remember the name and skip it */
-        strcpy (Name, SVal);
+        SB_Copy (Name, &CurTok.SVal);
         NextTok ();
 
         /* If no namespace symbol follows, we're already done */
-        if (Tok != TOK_NAMESPACE) {
-            SB_Terminate (ScopeName);
+        if (CurTok.Tok != TOK_NAMESPACE) {
+            SB_Terminate (FullName);
             return CurrentScope;
         }
 
         /* Pass the scope back to the caller */
-        SB_AppendStr (ScopeName, Name);
+        SB_Append (FullName, Name);
 
         /* The scope must exist, so search for it starting with the current
-         * scope.
-         */
+        ** scope.
+        */
         Scope = SymFindAnyScope (CurrentScope, Name);
         if (Scope == 0) {
             /* Scope not found */
-            SB_Terminate (ScopeName);
-            Error ("No such scope: `%s'", SB_GetConstBuf (ScopeName));
+            SB_Terminate (FullName);
+            Error ("No such scope: '%m%p'", FullName);
             return 0;
         }
 
@@ -101,103 +103,100 @@ SymTable* ParseScopedIdent (char* Name, StrBuf* ScopeName)
 
         /* Invalid token */
         Error ("Identifier expected");
-        SB_Terminate (ScopeName);
-        Name[0] = '\0';
         return 0;
 
     }
 
     /* Skip the namespace token that follows */
-    SB_AppendStr (ScopeName, "::");
+    SB_AppendStr (FullName, "::");
     NextTok ();
 
     /* Resolve scopes. */
     while (1) {
 
         /* Next token must be an identifier. */
-        if (Tok != TOK_IDENT) {
+        if (CurTok.Tok != TOK_IDENT) {
             Error ("Identifier expected");
-            SB_Terminate (ScopeName);
-            Name[0] = '\0';
             return 0;
         }
 
         /* Remember and skip the identifier */
-        strcpy (Name, SVal);
+        SB_Copy (Name, &CurTok.SVal);
         NextTok ();
 
         /* If a namespace token follows, we search for another scope, otherwise
-         * the name is a symbol and we're done.
-         */
-        if (Tok != TOK_NAMESPACE) {
+        ** the name is a symbol and we're done.
+        */
+        if (CurTok.Tok != TOK_NAMESPACE) {
             /* Symbol */
-            SB_Terminate (ScopeName);
             return Scope;
         }
 
         /* Pass the scope back to the caller */
-        SB_AppendStr (ScopeName, Name);
+        SB_Append (FullName, Name);
 
         /* Search for the child scope */
         Scope = SymFindScope (Scope, Name, SYM_FIND_EXISTING);
         if (Scope == 0) {
             /* Scope not found */
-            SB_Terminate (ScopeName);
-            Error ("No such scope: `%s'", SB_GetConstBuf (ScopeName));
+            Error ("No such scope: '%m%p'", FullName);
             return 0;
         }
 
         /* Skip the namespace token that follows */
-        SB_AppendStr (ScopeName, "::");
+        SB_AppendStr (FullName, "::");
         NextTok ();
     }
 }
 
 
 
-SymEntry* ParseScopedSymName (int AllocNew)
+SymEntry* ParseScopedSymName (SymFindAction Action)
 /* Parse a (possibly scoped) symbol name, search for it in the symbol table
- * and return the symbol table entry.
- */
+** and return the symbol table entry.
+*/
 {
-    StrBuf    ScopeName = AUTO_STRBUF_INITIALIZER;
-    char      Ident[sizeof (SVal)];
+    StrBuf    ScopeName = STATIC_STRBUF_INITIALIZER;
+    StrBuf    Ident = STATIC_STRBUF_INITIALIZER;
     int       NoScope;
     SymEntry* Sym;
 
     /* Parse the scoped symbol name */
-    SymTable* Scope = ParseScopedIdent (Ident, &ScopeName);
+    SymTable* Scope = ParseScopedIdent (&Ident, &ScopeName);
 
     /* If ScopeName is empty, no scope was specified */
     NoScope = SB_IsEmpty (&ScopeName);
 
     /* We don't need ScopeName any longer */
-    DoneStrBuf (&ScopeName);
+    SB_Done (&ScopeName);
 
     /* Check if the scope is valid. Errors have already been diagnosed by
-     * the routine, so just exit.
-     */
+    ** the routine, so just exit.
+    */
     if (Scope) {
         /* Search for the symbol and return it. If no scope was specified,
-         * search also in the upper levels.
-         */
-        if (NoScope && !AllocNew) {
-            Sym = SymFindAny (Scope, Ident);
+        ** search also in the upper levels.
+        */
+        if (NoScope && (Action & SYM_ALLOC_NEW) == 0) {
+            Sym = SymFindAny (Scope, &Ident);
         } else {
-            Sym = SymFind (Scope, Ident, AllocNew);
+            Sym = SymFind (Scope, &Ident, Action);
         }
     } else {
         /* No scope ==> no symbol. To avoid errors in the calling routine that
-         * may not expect NULL to be returned if AllocNew is true, create a new
-         * symbol.
-         */
-        if (AllocNew) {
-            Sym = NewSymEntry (Ident, SF_NONE);
+        ** may not expect NULL to be returned if Action contains SYM_ALLOC_NEW,
+        ** create a new symbol.
+        */
+        if (Action & SYM_ALLOC_NEW) { 
+            Sym = NewSymEntry (&Ident, SF_NONE);
         } else {
             Sym = 0;
         }
     }
 
+    /* Deallocate memory for ident */
+    SB_Done (&Ident);
+
     /* Return the symbol found */
     return Sym;
 }
@@ -206,37 +205,60 @@ SymEntry* ParseScopedSymName (int AllocNew)
 
 SymTable* ParseScopedSymTable (void)
 /* Parse a (possibly scoped) symbol table (scope) name, search for it in the
- * symbol space and return the symbol table struct.
- */
+** symbol space and return the symbol table struct.
+*/
 {
-    StrBuf    ScopeName = AUTO_STRBUF_INITIALIZER;
-    char      Name[sizeof (SVal)];
+    StrBuf    ScopeName = STATIC_STRBUF_INITIALIZER;
+    StrBuf    Name = STATIC_STRBUF_INITIALIZER;
     int       NoScope;
 
 
     /* Parse the scoped symbol name */
-    SymTable* Scope = ParseScopedIdent (Name, &ScopeName);
+    SymTable* Scope = ParseScopedIdent (&Name, &ScopeName);
 
     /* If ScopeName is empty, no scope was specified */
     NoScope = SB_IsEmpty (&ScopeName);
 
     /* We don't need FullName any longer */
-    DoneStrBuf (&ScopeName);
+    SB_Done (&ScopeName);
 
     /* If we got no error, search for the child scope withint the enclosing one.
-     * Beware: If no explicit parent scope was specified, search in all upper
-     * levels.
-     */
+    ** Beware: If no explicit parent scope was specified, search in all upper
+    ** levels.
+    */
     if (Scope) {
         /* Search for the last scope */
         if (NoScope) {
-            Scope = SymFindAnyScope (Scope, Name);
+            Scope = SymFindAnyScope (Scope, &Name);
         } else {
-            Scope = SymFindScope (Scope, Name, SYM_FIND_EXISTING);
+            Scope = SymFindScope (Scope, &Name, SYM_FIND_EXISTING);
         }
     }
+
+    /* Free memory for name */
+    SB_Done (&Name);
+
+    /* Return the scope found */
     return Scope;
 }
 
 
 
+SymEntry* ParseAnySymName (SymFindAction Action)
+/* Parse a cheap local symbol or a a (possibly scoped) symbol name, search
+** for it in the symbol table and return the symbol table entry.
+*/
+{
+    SymEntry* Sym;
+
+    /* Distinguish cheap locals and other symbols */
+    if (CurTok.Tok == TOK_LOCAL_IDENT) {
+        Sym = SymFindLocal (SymLast, &CurTok.SVal, Action);
+        NextTok ();
+    } else {
+        Sym = ParseScopedSymName (Action);
+    }
+
+    /* Return the symbol found */
+    return Sym;
+}