SYMBOL.C
上传用户:hlzzc88
上传日期:2007-01-06
资源大小:220k
文件大小:5k
源码类别:

编译器/解释器

开发平台:

Others

  1. /*
  2.  * 68K/386 32-bit C compiler.
  3.  *
  4.  * copyright (c) 1997, David Lindauer
  5.  * 
  6.  * This compiler is intended for educational use.  It may not be used
  7.  * for profit without the express written consent of the author.
  8.  *
  9.  * It may be freely redistributed, as long as this notice remains intact
  10.  * and either the original sources or derived sources 
  11.  * are distributed along with any executables derived from the originals.
  12.  *
  13.  * The author is not responsible for any damages that may arise from use
  14.  * of this software, either idirect or consequential.
  15.  *
  16.  * v1.35 March 1997
  17.  * David Lindauer, gclind01@starbase.spd.louisville.edu
  18.  *
  19.  * Credits to Mathew Brandt for original K&R C compiler
  20.  *
  21.  */
  22. /* Handles symbol tables 
  23.  */
  24. #include        <stdio.h>
  25. #include <malloc.h>
  26. #include        "expr.h"
  27. #include        "c.h"
  28. #include  "errors.h"
  29. #define ROTR(x,bits) (((x << (16 - bits)) | (x >> bits)) & 0xffff)
  30. #define ROTL(x,bits) (((x << bits) | (x >> (16 - bits))) & 0xffff)
  31. #define HASHTABLESIZE 1023
  32. extern TABLE oldlsym;
  33. extern int prm_cplusplus,prm_cmangle;
  34. HASHREC **globalhash=0;
  35. HASHREC **defhash=0;
  36. TABLE gsyms,lsyms,defsyms;
  37. void symini(void)
  38. {
  39. gsyms.head = gsyms.tail = lsyms.head = lsyms.tail = defsyms.head = defsyms.tail = 0;
  40. if (!globalhash) {
  41.    globalhash = (HASHREC *)malloc(HASHTABLESIZE * sizeof(HASHREC *));
  42.    defhash = (HASHREC *)malloc(HASHTABLESIZE * sizeof(HASHREC *));
  43. }
  44.   memset(globalhash,0,HASHTABLESIZE * sizeof(HASHREC *));
  45.   memset(defhash,0,HASHTABLESIZE * sizeof(HASHREC *));
  46. }
  47. /* Sym tab hash function */
  48. static unsigned int ComputeHash(char *string,int size)
  49. {
  50.   unsigned int len = strlen(string), rv;
  51.   char *pe = len + string;
  52.   unsigned char blank = ' ';
  53.   rv = len | blank;
  54.   while(len--) {
  55.     unsigned char cback = (unsigned char)(*--pe) | blank;
  56.     rv = ROTR(rv,2) ^ cback;
  57.   }
  58.   return(rv % size);
  59. }
  60. /* Add a hash item to the table */
  61. HASHREC *AddHash(HASHREC *item,HASHREC **table,int size)
  62. {
  63.   int index = ComputeHash(item->key,size);
  64.   HASHREC **p;
  65.   item->link = 0;
  66.   if (*(p = &table[index])) {
  67.     HASHREC *q = *p,*r = *p;
  68.     while (q) {
  69. r = q;
  70.       if (!strcmp(r->key,item->key))
  71. return(r);
  72. q = q->link;
  73. }
  74. r->link = item;
  75.   }
  76.   else
  77.     *p = item;
  78.   return(0);
  79. }
  80. /*
  81.  * Find something in the hash table
  82.  */
  83. HASHREC **LookupHash(char *key, HASHREC **table, int size)
  84. {
  85.   int index = ComputeHash(key,size);
  86.   HASHREC **p;
  87.   if (*(p = &table[index])) {
  88.     HASHREC *q= *p;
  89.     while (q) {
  90.       if (!strcmp(q->key, key))
  91. return(p);
  92. p = *p;
  93. q=q->link;
  94. }
  95. }
  96. return(0);
  97. }
  98. /*
  99.  * Some tables use hash tables and some use linked lists
  100.  * This is the global symbol search routine
  101.  */
  102. SYM     *search(char *na,TABLE *table)
  103. {
  104. SYM *thead = table->head;
  105. SYM **p;
  106. if (table == &gsyms) {
  107. p=((SYM **)LookupHash(na,globalhash,HASHTABLESIZE));
  108. if (p)
  109. p = *p;
  110. return (SYM *) p;
  111. }
  112. else if (table == &defsyms) {
  113. p=((SYM **)LookupHash(na,defhash,HASHTABLESIZE));
  114. if (p)
  115. p = *p;
  116. return (SYM *) p;
  117. }
  118. else
  119.        while( thead != 0) {
  120.                 if(strcmp(thead->name,na) == 0)
  121.                         return thead;
  122.                 thead = thead->next;
  123.                 }
  124.         return 0;
  125. }
  126. SYM     *gsearch(char *na)
  127. {       SYM     *sp;
  128.         if( (sp = search(na,&lsyms)) == 0)
  129.                 sp = search(na,&gsyms);
  130.         return sp;
  131. }
  132. /* The global symbol insert routine */
  133. void insert(SYM *sp,TABLE *table)
  134. {
  135. if (table == &gsyms) {
  136. if (AddHash(sp,globalhash,HASHTABLESIZE))
  137. gensymerror(ERR_DUPSYM,sp->name);
  138. }
  139.   else if (table == &defsyms) {
  140. AddHash(sp,defhash,HASHTABLESIZE);
  141. }
  142. else if (table == &lsyms) {
  143. SYM *thead = table->head,*qhead = 0;
  144. /* Only check the current local block... */
  145.   while( thead != oldlsym.head) {
  146.         if(strcmp(thead->name,sp->name) == 0) {
  147.               qhead = thead;
  148.   break;
  149. }
  150.         thead = thead->next;
  151.         }
  152. if (qhead) 
  153.        gensymerror(ERR_DUPSYM,sp->name);
  154. else {
  155. /* Putting local symbols in backwards */
  156.       if( table->head == 0) {
  157.         table->head = table->tail = sp;
  158.        sp->next = 0;
  159. }
  160.       else    {
  161. sp->next = table->head;
  162. table->head = sp;
  163.       }
  164. }
  165. }
  166. else if( search(sp->name,table) == 0) {
  167.                 if( table->head == 0)
  168.                         table->head = table->tail = sp;
  169.                 else    {
  170.                         table->tail->next = sp;
  171.                         table->tail = sp;
  172.                         }
  173.                 sp->next = 0;
  174.                 }
  175.         else
  176.                 gensymerror(ERR_DUPSYM,sp->name);
  177. }