home *** CD-ROM | disk | FTP | other *** search
/ GEMini Atari / GEMini_Atari_CD-ROM_Walnut_Creek_December_1993.iso / files / language / asxsrc / lksym.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-08-25  |  3.9 KB  |  247 lines

  1. /* lksym.c */
  2.  
  3. /*
  4.  * (C) Copyright 1989
  5.  * All Rights Reserved
  6.  *
  7.  * Alan R. Baldwin
  8.  * 721 Berkeley St.
  9.  * Kent, Ohio  44240
  10.  */
  11.  
  12. #include <stdio.h>
  13. #include "aslink.h"
  14.  
  15. /*
  16.  * This routine is called early in the
  17.  * game to set up the symbol hashtable.
  18.  */
  19. VOID
  20. syminit()
  21. {
  22.     register h;
  23.     struct sym **spp;
  24.  
  25.     spp = &symhash[0];
  26.     while (spp < &symhash[NHASH])
  27.         *spp++ = NULL;
  28. }
  29.  
  30. /*
  31.  * Find/Create a global symbol entry.
  32.  *
  33.  * S xxxxxx Defnnnn
  34.  *   |      |  |
  35.  *   |      |  `-- sp->s_addr
  36.  *   |      `----- sp->s_type
  37.  *   `------------ sp->s_id
  38.  *
  39.  */
  40. struct sym *
  41. newsym()
  42. {
  43.     register c, i, nglob;
  44.     struct sym *tsp;
  45.     struct sym **s;
  46.     char id[NCPS];
  47.  
  48.     getid(id, -1);
  49.     tsp = lkpsym(id, 1);
  50.     c = getnb();get();get();
  51.     if (c == 'R') {
  52.         tsp->s_type |= S_REF;
  53.         if (eval())
  54.             fprintf(stderr, "Non zero S_REF\n");
  55.     } else
  56.     if (c == 'D') {
  57.         i = eval();
  58.         if (tsp->s_type & S_DEF && tsp->s_addr != i)
  59.             fprintf(stderr, "Multiple definition of %.8s\n", id);
  60.         tsp->s_type |= S_DEF;
  61.         /*
  62.          * Set value and area extension link.
  63.          */
  64.         tsp->s_addr = i;
  65.         tsp->s_axp = axp;
  66.     } else {
  67.         fprintf(stderr, "Invalid symbol type %c for %.8s\n", c, id);
  68.         exit(1);
  69.     }
  70.     /*
  71.      * Place pointer in header symbol list
  72.      */
  73.     if (headp == NULL) {
  74.         fprintf(stderr, "No header defined\n");
  75.         exit(1);
  76.     }
  77.     nglob = hp->h_nglob;
  78.     s = (struct sym **) hp->s_list;
  79.     for (i=0; i < nglob ;++i) {
  80.         if (s[i] == NULL) {
  81.             s[i] = tsp;
  82.             return(tsp);
  83.         }
  84.     }
  85.     fprintf(stderr, "Header symbol list overflow\n");
  86.     exit(1);
  87. }
  88.  
  89. /*
  90.  * Lookup the name `id' in the hashtable.
  91.  * If it is not found either return a
  92.  * `NULL' (`f' is false) or a
  93.  * pointer to a newly created hash table
  94.  * entry (`f' is true).
  95.  */
  96. struct sym *
  97. lkpsym(id, f)
  98. char *id;
  99. {
  100.     register struct sym *sp;
  101.     register h;
  102.  
  103.     h = hash(id);
  104.     sp = symhash[h];
  105.     while (sp != NULL) {
  106.         if (symeq(id, sp->s_id))
  107.             return (sp);
  108.         sp = sp->s_sp;
  109.     }
  110.     if (f == 0)
  111.         return (NULL);
  112.     sp = (struct sym *) new (sizeof(struct sym));
  113.     sp->s_sp = symhash[h];
  114.     symhash[h] = sp;
  115.     strncpy(sp->s_id, id, NCPS);
  116.     return (sp);
  117. }
  118.  
  119. /*
  120.  * Get value of relocated symbol
  121.  */
  122. int
  123. symval(tsp)
  124. register struct sym *tsp;
  125. {
  126.     register val;
  127.  
  128.     val = tsp->s_addr;
  129.     if (tsp->s_axp) {
  130.         val += tsp->s_axp->a_addr;
  131.     }
  132.     return(val);
  133. }
  134.  
  135. /*
  136.  * Check for undefined symbols
  137.  */
  138. VOID
  139. symdef(fp)
  140. FILE *fp;
  141. {
  142.     register struct sym *sp;
  143.     register i;
  144.  
  145.     for (i=0; i<NHASH; ++i) {
  146.         sp = symhash[i];
  147.         while (sp) {
  148.             if (sp->s_axp == NULL)
  149.                 sp->s_axp = areap->a_axp;
  150.             if ((sp->s_type & S_DEF) == 0)
  151.                 symmod(fp, sp);
  152.             sp = sp->s_sp;
  153.         }
  154.     }
  155. }
  156.  
  157. VOID
  158. symmod(fp, tsp)
  159. FILE *fp;
  160. struct sym *tsp;
  161. {
  162.     register i, j;
  163.     struct sym **p;
  164.  
  165.     if (hp = headp) {
  166.         while(hp) {
  167.         p = (struct sym **) hp->s_list;
  168.         for (i=0; i<hp->h_nglob; ++i) {
  169.             if (p[i] == tsp) {
  170.             fprintf(fp, "Undefined Global %8.8s ", tsp->s_id);
  171.             fprintf(fp, "referenced by module %8.8s\n", hp->m_id);
  172.             }
  173.         }
  174.         hp = hp->h_hp;
  175.         }
  176.     }
  177. }
  178.  
  179. /*
  180.  * Compare two symbol names.
  181.  */
  182. int
  183. symeq(p1, p2)
  184. register char *p1, *p2;
  185. {
  186.     register n;
  187.  
  188.     n = NCPS;
  189.     do {
  190.  
  191. #if    CASE_SENSITIVE
  192.         if (*p1++ != *p2++)
  193.             return (0);
  194. #else
  195.         if (ccase[*p1++] != ccase[*p2++])
  196.             return (0);
  197. #endif
  198.  
  199.     } while (--n);
  200.     return (1);
  201. }
  202.  
  203. /*
  204.  * Given a pointer to a symbol name
  205.  * compute and return the hash table
  206.  * bucket.
  207.  * The `sum of all the characters mod
  208.  * table size' algorithm is perhaps
  209.  * not the best.
  210.  */
  211. int
  212. hash(p)
  213. register char *p;
  214. {
  215.     register h, n;
  216.  
  217.     h = 0;
  218.     n = NCPS;
  219.     do {
  220.  
  221. #if    CASE_SENSITIVE
  222.         h += *p++;
  223. #else
  224.         h += ccase[*p++];
  225. #endif
  226.  
  227.     } while (--n);
  228.     return (h&HMASK);
  229. }
  230.  
  231. /*
  232.  * Allocate and clear a block of space.
  233.  * Leave if there is no space left
  234.  * at all.
  235.  */
  236. VOID *
  237. new(n)
  238. {
  239.     register VOID *p;
  240.  
  241.     if ((p = (VOID *) calloc(n,1)) == NULL) {
  242.         fprintf(stderr, "Out of space!\n");
  243.         exit(1);
  244.     }
  245.     return (p);
  246. }
  247.