]> Shamusworld >> Repos - rmac/blobdiff - symbol.c
Fix for "*" getting bad section attributes, reported by A. Seed.
[rmac] / symbol.c
index 25829f41f7bbbdf5fc296a45fd28489f3afdcf49..9ba661fc3fa931609a7f34eb1c95c5aa84d33d6c 100644 (file)
--- a/symbol.c
+++ b/symbol.c
@@ -3,7 +3,7 @@
 // SYMBOL.C - Symbol Handling
 // Copyright (C) 199x Landon Dyer, 2011-2012 Reboot and Friends
 // RMAC derived from MADMAC v1.07 Written by Landon Dyer, 1986
-// Source Utilised with the Kind Permission of Landon Dyer
+// Source utilised with the kind permission of Landon Dyer
 //
 
 #include "symbol.h"
 #include "procln.h"
 #include "error.h"
 
-static SYM * sytab[NBUCKETS];                               // User symbol-table header
-int curenv;                                                 // Current enviroment number
-SYM * sorder;                                               // * -> Symbols, in order of reference
-SYM * sordtail;                                             // * -> Last symbol in sorder list
-SYM * sdecl;                                                // * -> Symbols, in order of declaration
-SYM * sdecltail;                                            // * -> Last symbol in sdecl list
+
+// Macros
+#define NBUCKETS 256                                   // Number of hash buckets (power of 2)
+
+static SYM * symbolTable[NBUCKETS];            // User symbol-table header
+int curenv;                                                            // Current enviroment number
+static SYM * sorder;                                   // * -> Symbols, in order of reference
+static SYM * sordtail;                                 // * -> Last symbol in sorder list
+static SYM * sdecl;                                            // * -> Symbols, in order of declaration
+static SYM * sdecltail;                                        // * -> Last symbol in sdecl list
+static uint32_t currentUID;                            // Symbol UID tracking (done by NewSymbol())
 
 // Tags for marking symbol spaces
 // a = absolute
@@ -30,54 +35,32 @@ static char tdb_text[8] = {
 
 
 //
-// Initialize Symbol Table
+// Initialize symbol table
 //
-void init_sym(void)
+void InitSymbolTable(void)
 {
-       int i;                                                   // Iterator
+       int i;                                                                  // Iterator
 
-       for(i=0; i<NBUCKETS; ++i)                            // Initialise symbol hash table
-               sytab[i] = NULL;
+       for(i=0; i<NBUCKETS; i++)                               // Initialise symbol hash table
+               symbolTable[i] = NULL;
 
-       curenv = 1;                                              // Init local symbol enviroment
-       sorder = NULL;                                           // Init symbol-reference list
+       curenv = 1;                                                             // Init local symbol enviroment
+       sorder = NULL;                                                  // Init symbol-reference list
        sordtail = NULL;
-       sdecl = NULL;                                            // Init symbol-decl list
+       sdecl = NULL;                                                   // Init symbol-decl list
        sdecltail = NULL;
+       currentUID = 0;
 }
 
 
 //
-// Allocate and Return Pointer to a Copy of a String
+// Hash the print name and enviroment number
 //
-char * nstring(char * str)
+int HashSymbol(char * name, int envno)
 {
-       long i;
-       char * s, * d;
-
-       for(i=0; str[i]; ++i)
-               ;
-
-       s = d = amem(i + 1);
-
-       while (*str)
-               *d++ = *str++;
-
-       *d++ = '\0';
-       
-       return s;
-}
+       int sum, k = 0;                                                 // Hash calculation
 
-
-//
-// Hash the Print Name and Enviroment Number
-//
-int syhash(char * name, int envno)
-{
-       int sum, k;                                              // Hash calculation
-       k = 0;
-
-       for(sum=envno; *name; ++name)
+       for(sum=envno; *name; name++)
        {
                if (k++ == 1)
                        sum += *name << 2;
@@ -92,131 +75,139 @@ int syhash(char * name, int envno)
 //
 // Make a new symbol of type `type' in enviroment `envno'
 //
-SYM * newsym(char * name, int type, int envno)
+SYM * NewSymbol(char * name, int type, int envno)
 {
-       int hash;                                                // Symbol hash value
-       SYM * sy;                                                // Pointer to symbol
-
        // Allocate the symbol
-       sy = (SYM *)amem((long)(sizeof(SYM)));
+       SYM * symbol = malloc(sizeof(SYM));
 
-       if (sy == NULL)
+       if (symbol == NULL)
        {
-               printf("SYMALLOC ERROR (%s)\n", name);
+               printf("NewSymbol: MALLOC ERROR (symbol=\"%s\")\n", name);
                return NULL;
        }
 
-       sy->sname = nstring(name);
-
        // Fill-in the symbol
-       sy->stype  = (BYTE)type;
-       sy->senv   = (WORD)envno;
-       sy->sattr  = 0;
-
-       if (rgpu || rdsp)
-               sy->sattre = RISCSYM;
-       else
-               sy->sattre = 0;
-
-       sy->svalue = 0;
+       symbol->sname  = strdup(name);
+       symbol->stype  = (BYTE)type;
+       symbol->senv   = (WORD)envno;
+       symbol->sattr  = 0;
+       // Don't do this, it could be a forward reference!
+//     symbol->sattr  = DEFINED;               // We just defined it...
+       // This is a bad assumption. Not every symbol 1st seen in a RISC section is
+       // a RISC symbol!
+//     symbol->sattre = (rgpu || rdsp ? RISCSYM : 0);
+       symbol->sattre = 0;
+       symbol->svalue = 0;
+       symbol->sorder = NULL;
+       symbol->uid    = currentUID++;
 
        // Install symbol in symbol table
-       hash = syhash(name, envno);
-       sy->snext = sytab[hash];
-       sytab[hash] = sy;
+       int hash = HashSymbol(name, envno);
+       symbol->snext = symbolTable[hash];
+       symbolTable[hash] = symbol;
 
        // Append symbol to symbol-order list
        if (sorder == NULL)
-               sorder = sy;                                          // Add first symbol 
+               sorder = symbol;                                        // Add first symbol 
        else
-               sordtail->sorder = sy;                                // Or append to tail of list
+               sordtail->sorder = symbol;                      // Or append to tail of list
 
-       sy->sorder = NULL;
-       sordtail = sy;
-
-       return sy;                                              // Return pointer to symbol
+       sordtail = symbol;
+       return symbol;
 }
 
 
 //
-// Lookup the symbol `name', of the specified type, with the specified
-// enviroment level
+// Look up the symbol name by its UID and return the pointer to the name.
+// If it's not found, return NULL.
 //
-SYM * lookup(char * name, int type, int envno)
+char * GetSymbolNameByUID(uint32_t uid)
 {
-       SYM * sy;                                                // Symbol record pointer
-       int k, sum;                                              // Hash bucket calculation
-       char * s;                                                // String pointer
+       //problem is with string lookup, that's why we're writing this
+       //so once this is written, we can put the uid in the token stream
 
-       // Pick a hash-bucket (SAME algorithm as syhash())
-       k = 0;
-       s = name;
+       // A much better approach to the symbol order list would be to make an
+       // array--that way you can do away with the UIDs and all the rest, and
+       // simply do an array lookup based on position. But meh, let's do this for
+       // now until we can rewrite things so they make sense.
+       SYM * symbol = sorder;
 
-       for(sum=envno; *s;)
+       for(; symbol; symbol=symbol->sorder)
        {
-               if (k++ == 1)
-                       sum += *s++ << 2;
-               else
-                       sum += *s++;
+               if (symbol->uid == uid)
+                       return symbol->sname;
        }
 
-       sy = sytab[sum & (NBUCKETS-1)];
+       return NULL;
+}
+
+
+//
+// Lookup the symbol `name', of the specified type, with the specified
+// enviroment level
+//
+SYM * lookup(char * name, int type, int envno)
+{
+       SYM * symbol = symbolTable[HashSymbol(name, envno)];
 
        // Do linear-search for symbol in bucket
-       while (sy != NULL)
+       while (symbol != NULL)
        {
-               if (sy->stype == type &&                         // Type, envno and name must match
-                       sy->senv  == envno &&
-                       *name == *sy->sname &&                         // Fast check for first character
-                       !strcmp(name, sy->sname))
+               if (symbol->stype == type                       // Type, envno and name must match
+                       && symbol->senv  == envno
+                       && *name == *symbol->sname              // Fast check for first character
+                       && !strcmp(name, symbol->sname))        // More expensive check
                        break;
-               else
-                       sy = sy->snext;
+
+               symbol = symbol->snext;
        }
 
-       return sy;                                              // Return NULL or matching symbol
+       // Return NULL or matching symbol
+       return symbol;
 }
 
 
 //
 // Put symbol on "order-of-declaration" list of symbols
 //
-void sym_decl(SYM * sym)
+void AddToSymbolDeclarationList(SYM * symbol)
 {
-       if (sym->sattr & SDECLLIST)
-               return;                                                         // Already on list
+       // Don't add if already on list, or it's an equated register/CC
+       if ((symbol->sattr & SDECLLIST)
+               || (symbol->sattre & (EQUATEDREG | UNDEF_EQUR | EQUATEDCC | UNDEF_CC)))
+               return;
 
-       sym->sattr |= SDECLLIST;                                // Mark "already on list"
+       // Mark as "on .sdecl list"
+       symbol->sattr |= SDECLLIST;
 
        if (sdecl == NULL)
-               sdecl = sym;                                            // First on decl-list
+               sdecl = symbol;                         // First on decl-list
        else 
-               sdecltail->sdecl = sym;                         // Add to end of list
+               sdecltail->sdecl = symbol;      // Add to end of list
 
-       sym->sdecl = NULL;                                              // Fix up list's tail
-       sdecltail = sym;
+       // Fix up list's tail
+       symbol->sdecl = NULL;
+       sdecltail = symbol;
 }
 
 
 //
 // Make all referenced, undefined symbols global
 //
-int syg_fix(void)
+void ForceUndefinedSymbolsGlobal(void)
 {
        SYM * sy;
 
-       DEBUG printf("~syg_fix()\n");
+       DEBUG printf("~ForceUndefinedSymbolsGlobal()\n");
 
        // Scan through all symbols;
        // If a symbol is REFERENCED but not DEFINED, then make it global.
-       for(sy = sorder; sy != NULL; sy = sy->sorder)
+       for(sy=sorder; sy!=NULL; sy=sy->sorder)
        {
                if (sy->stype == LABEL && sy->senv == 0
-                       && ((sy->sattr & (REFERENCED|DEFINED)) == REFERENCED))
+                       && ((sy->sattr & (REFERENCED | DEFINED)) == REFERENCED))
                        sy->sattr |= GLOBAL;
        }
-
-       return 0;
 }
 
 
@@ -225,7 +216,7 @@ int syg_fix(void)
 //
 int uc_string(char * s)
 {
-       for(; *s; ++s)
+       for(; *s; s++)
        {
                if (*s >= 'a' && *s <= 'z')
                        *s -= 32;
@@ -240,50 +231,32 @@ int uc_string(char * s)
 // number is put in `.senv'. Return the number of symbols that will be in the
 // symbol table.
 //
-int sy_assign(char * buf, char *(*constr)())
+int sy_assign(char * buf, char *(* constr)())
 {
        SYM * sy;
-       int scount;
-       //int i;
-
-       scount = 0;
+       int scount = 0;
 
        if (buf == NULL)
        {
                // Append all symbols not appearing on the .sdecl list to the end of
                // the .sdecl list
                for(sy=sorder; sy!=NULL; sy=sy->sorder)
-               {
-                       // Essentially the same as 'sym_decl()' above:
-                       if (sy->sattr & SDECLLIST)
-                               continue;                // Already on list 
-
-                       sy->sattr |= SDECLLIST;                            // Mark "on the list"
-
-                       if (sdecl == NULL)
-                               sdecl = sy;                      // First on decl-list 
-                       else
-                               sdecltail->sdecl = sy;                        // Add to end of list
-
-                       sy->sdecl = NULL;                                  // Fix up list's tail
-                       sdecltail = sy;
-               }
+                       AddToSymbolDeclarationList(sy);
        }
 
        // Run through all symbols (now on the .sdecl list) and assign numbers to
        // them. We also pick which symbols should be global or not here.
        for(sy=sdecl; sy!=NULL; sy=sy->sdecl)
        {
-               if (sy->sattre & UNDEF_EQUR)
-                       continue;                 // Don't want undefined on our list
+               // Don't want register/CC or undefined on our list
+//these should already be rejected above...
+//             if (sy->sattre & (EQUATEDREG | UNDEF_EQUR | EQUATEDCC | UNDEF_CC)))
+//                     continue;
 
-               if (sy->sattre & UNDEF_CC)
-                       continue;                   
-               
                // Export or import external references, and export COMMON blocks.
                if ((sy->stype == LABEL)
-                       && ((sy->sattr & (GLOBAL|DEFINED)) == (GLOBAL|DEFINED)
-                       || (sy->sattr & (GLOBAL|REFERENCED)) == (GLOBAL|REFERENCED))
+                       && ((sy->sattr & (GLOBAL | DEFINED)) == (GLOBAL | DEFINED)
+                       || (sy->sattr & (GLOBAL | REFERENCED)) == (GLOBAL | REFERENCED))
                        || (sy->sattr & COMMON))
                {
                        sy->senv = (WORD)scount++;
@@ -294,11 +267,13 @@ int sy_assign(char * buf, char *(*constr)())
                // Export vanilla labels (but don't make them global). An exception is
                // made for equates, which are not exported unless they are referenced.
                else if (sy->stype == LABEL && lsym_flag
-                       && (sy->sattr & (DEFINED|REFERENCED)) != 0
+                       && (sy->sattr & (DEFINED | REFERENCED)) != 0
                        && (!as68_flag || *sy->sname != 'L'))
                {
                        sy->senv = (WORD)scount++;
-                       if (buf != NULL) buf = (*constr)(buf, sy, 0);
+
+                       if (buf != NULL)
+                               buf = (*constr)(buf, sy, 0);
                }
        }
 
@@ -332,40 +307,40 @@ int symtable(void)
 
        // Allocate storage for list headers and partition all labels.  
        // Throw away macros and macro arguments.
-       sy = (SYM **)amem((LONG)(128 * sizeof(LONG)));
+       sy = (SYM **)malloc(128 * sizeof(LONG));
 
        for(i=0; i<128; ++i)
                sy[i] = NULL;
 
        for(i=0; i<NBUCKETS; ++i)
        {
-               for(p=sytab[i]; p!=NULL; p=k)
+               for(p=symbolTable[i]; p!=NULL; p=k)
                {
                        k = p->snext;
                        j = *p->sname;
                        r = NULL;
 
-                       if (p->stype != LABEL)
-                               continue;                    // Ignore non-labels
-
-                       if (p->sattre & UNDEF_EQUR)
+                       // Ignore non-labels
+                       if ((p->stype != LABEL) || (p->sattre & UNDEF_EQUR))
                                continue;
 
                        for(q=sy[j]; q!=NULL; q=q->snext)
                        {
                                if (strcmp(p->sname, q->sname) < 0)
                                        break;
-                               else
-                                       r = q;
+
+                               r = q;
                        }
 
                        if (r == NULL)
-                       {                                    // Insert at front of list
+                       {
+                               // Insert at front of list
                                p->snext = sy[j];
                                sy[j] = p;
                        }
                        else
-                       {                                           // Insert in middle or append to list
+                       {
+                               // Insert in middle or append to list
                                p->snext = r->snext;
                                r->snext = p;
                        }
@@ -446,7 +421,7 @@ int symtable(void)
                                        strcpy(ln2, "external");
                                else
                                {
-                                       sprintf(ln2, "%08ux", q->svalue);
+                                       sprintf(ln2, "%08X", q->svalue);
                                        uc_string(ln2);
                                }
 
@@ -462,3 +437,4 @@ int symtable(void)
 
        return 0;
 }
+