home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / vol_300 / 363_02 / symbol.c < prev    next >
C/C++ Source or Header  |  1991-12-17  |  6KB  |  190 lines

  1. /***********************************************************************
  2.  *
  3.  *  SYMBOL.C
  4.  *  Symbol Handling Routines for 68020 Assembler
  5.  *
  6.  *  Function: create()
  7.  *  Pass 1:
  8.  *      If the symbol has not been created earlier creates a new symbol and
  9.  *      clears the flags. If the symbol exists MULTDEF flag is set.
  10.  *  Pass 2:
  11.  *      If      MULTDEF flag is set then MULTIPLE_DEFS error is issued,
  12.  *      else if value passed is different from value stored then PHASE_ERROR
  13.  *              is issued,
  14.  *      else    BACKREF flag is set so that all references to
  15.  *              that symbol encountered before this point are known to be
  16.  *              forward references, encountered after this point - backward
  17.  *              references.
  18.  *
  19.  *      In addition in all cases the routine returns a pointer to the 
  20.  *      structure (type symbolDef) which contains the symbol that was found
  21.  *      or created. The routine uses a hash function to index into an array
  22.  *      of pointers to ordered linked lists of symbol definitions.
  23.  *
  24.  *      Note: no use is made of the ordering of the list, it could just as
  25.  *      well be unordered.
  26.  *
  27.  *      create() is called by modules 'assemble', 'directiv', and 'movem'
  28.  *      
  29.  *
  30.  *  Function: lookup()
  31.  *      Searches the symbol table for the symbol whose name is specified.
  32.  *      If      the symbol exists the pointer to the symbolDef structure is
  33.  *              returned,
  34.  *      else    UNDEFINED error is issued and NULL is returned.
  35.  *
  36.  *      lookup() is called by modules directiv, eval, movem, and opparse;
  37.  *
  38.  *   Usage: symbolDef *create(char *sym, long value, int *errorPtr)
  39.  *          symbolDef *lookup(char *sym, int *errorPtr)
  40.  *
  41.  *      Author: Paul McKee
  42.  *      ECE492    North Carolina State University,  11/28/86
  43.  *
  44.  *      Modified A.E. Romer. Version 1.0
  45.  *          17 March 1991. ANSI function definitions.
  46.  *          31 March 1991. Bug corrected. Multiple symbol definitions were not 
  47.  *                         flagged as errors.
  48.  *
  49.  ************************************************************************/
  50.  
  51.  
  52. #include <stdio.h>
  53. #include <ctype.h>
  54. #include "asm.h"
  55.  
  56. /* HASHSIZE is the range of the hash function. hash()
  57.    returns values from 0 to HASHSIZE-1. */
  58.     
  59. #define HASHSIZE 27
  60.  
  61. static symbolDef *htable[HASHSIZE];
  62. extern char pass2;                           /* Flag set during second pass */
  63.  
  64.  
  65. void hashInit(void)                                /* initialize hash table */
  66.     {
  67.     int h;
  68.  
  69.     for (h = 0; h < HASHSIZE; h++)
  70.         htable[h] = NULL;
  71.     }
  72.  
  73.  
  74. int hash(char *symbol)                 /* evaluate hash No for given symbol */
  75.     {
  76.     int sum;
  77.  
  78.     sum = 0;
  79.     while (*symbol)
  80.         {
  81.         sum += (isupper(*symbol)) ? (*symbol - 'A') : 26;
  82.         symbol++;
  83.         }
  84.     return (sum % HASHSIZE);
  85.     }
  86.  
  87.  
  88. symbolDef *create(char *sym, long value, int *errorPtr)
  89.     {
  90.     int h, cmp;
  91.     symbolDef *s, *last, *t;
  92.     h = hash(sym);
  93.  
  94.     if ((s = htable[h]) != NULL)         /* at least one entry at this hash */
  95.         {
  96.  
  97.         /* Search the linked list for a matching symbol */
  98.         last = NULL;
  99.         while (s && (cmp = strcmp(s->name, sym)) < 0)
  100.                                                /* find nearest lower symbol */
  101.             {
  102.             last = s;
  103.             s = s->next;
  104.             }
  105.  
  106.         if (s && (cmp == 0))                                 /* match found */
  107.             {
  108.             if (!pass2)                                           /* pass 1 */
  109.                 s->flags |= MULTDEF;                            /* set flag */
  110.             else                                                  /* pass 2 */
  111.                 if (value != s->value)
  112.                     {
  113.                     NEWERROR(*errorPtr, PHASE_ERROR);
  114.                     }
  115.                 else if (s->flags & MULTDEF)
  116.                     {
  117.                     NEWERROR(*errorPtr, MULTIPLE_DEFS);
  118.                     }
  119.                 else
  120.                     s->flags |= BACKREF;
  121.             t = s;
  122.             }
  123.  
  124.         /* No match. Insert the symbol in the list, between lower and higher
  125.          * symbol (ordered list) */
  126.         else if (!pass2)
  127.             if (last)               /* there are higher entries, the symbol
  128.                                      * goes after an existing symbol */
  129.                 {
  130.                 t = (symbolDef *) malloc(sizeof(symbolDef));
  131.                 last->next = t;
  132.                 t->next = s;
  133.                 strcpy(t->name, sym);
  134.                 t->value = value;
  135.                 t->flags = 0;
  136.                 }
  137.             else                    /* no higher entries, the symbol
  138.                                      * goes at the head of a list */
  139.                 {
  140.                 t= (symbolDef *) malloc(sizeof(symbolDef));
  141.                 t->next = htable[h];
  142.                 htable[h] = t;
  143.                 strcpy(t->name, sym);
  144.                 t->value = value;
  145.                 t->flags = 0;
  146.                 }
  147.         }
  148.  
  149.     else                        /* No entry at this hash. Must be pass 1,
  150.                                  * in pass 2 the entry would be there */
  151.  
  152.         {
  153.         t = (symbolDef *) malloc(sizeof(symbolDef));
  154.         htable[h] = t;
  155.         t->next = NULL;
  156.         strcpy(t->name, sym);
  157.         t->value = value;
  158.         t->flags = 0;
  159.         }
  160.     return t;
  161.     }
  162.  
  163.  
  164. symbolDef *lookup(char *sym, int *errorPtr)
  165.     {
  166.     symbolDef *s;
  167.     int cmp;
  168.  
  169.     if ((s = htable[hash(sym)]) == NULL)           /* no entry at this hash */
  170.         {
  171.         NEWERROR(*errorPtr, UNDEFINED);
  172.         return NULL;
  173.         }
  174.  
  175. /* There is an entry, search the linked list for a matching symbol */
  176.  
  177.     while (s && (cmp = strcmp(s->name, sym)) < 0)
  178.                                                /* find nearest lower symbol */
  179.         s = s->next;
  180.  
  181.     if (cmp == 0)                                            /* match found */
  182.         return s;
  183.     else                                                        /* no match */
  184.         {
  185.         NEWERROR(*errorPtr, UNDEFINED);
  186.         return NULL;
  187.         }
  188.     }
  189.  
  190.