home *** CD-ROM | disk | FTP | other *** search
/ CD Shareware Magazine 1996 December / CD_shareware_12-96.iso / DOS / Programa / CCDL122.ZIP / SOURCE / SYMBOL.NEW < prev    next >
Encoding:
Text File  |  1996-08-05  |  12.3 KB  |  574 lines

  1. /*
  2.  * 68K/386 32-bit C compiler.
  3.  *
  4.  * copyright (c) 1996, 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 sources are distributed along with any executables derived from them.
  11.  *
  12.  * The author is not responsible for damages, either direct or consequential,
  13.  * that may arise from use of this software.
  14.  *
  15.  * v1.5 August 1996
  16.  * David Lindauer, gclind01@starbase.spd.louisville.edu
  17.  *
  18.  * Credits to Mathew Brandt for original K&R C compiler
  19.  *
  20.  */
  21. #include        <stdio.h>
  22. #include                <malloc.h>
  23. #include        "expr.h"
  24. #include        "c.h"
  25. #include        "gen.h"
  26. #include        "cglbdec.h"
  27. #define ROTR(x,bits) (((x << (16 - bits)) | (x >> bits)) & 0xffff)
  28. #define ROTL(x,bits) (((x << bits) | (x >> (16 - bits))) & 0xffff)
  29.  
  30. extern TABLE oldlsym;
  31. extern int prm_cplusplus,prm_cmangle;
  32. HASHREC **globalhash=0;
  33. HASHREC **defhash=0;
  34. #define HASHTABLESIZE 1023
  35.  
  36. char destructor_name[] = "$dtr";
  37. char constructor_name[] = "$ctr";
  38.  
  39. char *tn_void = "void";
  40. char *tn_char = "char";
  41. char *tn_int = "int";
  42. char *tn_long = "long" ;
  43. char *tn_short = "short";
  44. char *tn_unsigned = "unsigned ";
  45. char *tn_ellipse = "...";
  46. char *tn_float = "float";
  47. char *tn_double = "double";
  48. char *tn_longdouble = "long double";
  49. void symini(void)
  50. {
  51.     if (!globalhash) {
  52.       globalhash = (HASHREC *)malloc(HASHTABLESIZE * sizeof(HASHREC *));
  53.       defhash = (HASHREC *)malloc(HASHTABLESIZE * sizeof(HASHREC *));
  54.     }
  55.   memset(globalhash,0,HASHTABLESIZE * sizeof(HASHREC *));
  56.   memset(defhash,0,HASHTABLESIZE * sizeof(HASHREC *));
  57. }
  58.     
  59. static unsigned int ComputeHash(char *string,int size)
  60. {
  61.   unsigned int len = strlen(string), rv;
  62.   char *pe = len + string;
  63.   unsigned char blank = ' ';
  64.  
  65.   rv = len | blank;
  66.   while(len--) {
  67.     unsigned char cback = (*--pe) | blank;
  68.     rv = ROTR(rv,2) ^ cback;
  69.   }
  70.   return(rv % size);
  71. }
  72. HASHREC *AddHash(HASHREC *item,HASHREC **table,int size)
  73. {
  74.   int index = ComputeHash(item->key,size);
  75.   HASHREC **p;
  76.  
  77.   item->link = 0;
  78.  
  79.   if (*(p = &table[index])) {
  80.     HASHREC *q = *p,*r = *p;
  81.     while (q) {
  82.             r = q;
  83.       if (!strcmp(r->key,item->key))
  84.                 return(r);
  85.             q = q->link;
  86.         }
  87.         r->link = item;
  88.   }
  89.   else
  90.     *p = item;
  91.   return(0);
  92. }
  93. /*
  94.  * Find something in the hash table
  95.  */
  96. HASHREC **LookupHash(char *key, HASHREC **table, int size)
  97. {
  98.   int index = ComputeHash(key,size);
  99.   HASHREC **p;
  100.  
  101.   if (*(p = &table[index])) {
  102.     HASHREC *q= *p;
  103.     while (q) {
  104.       if (!strcmp(q->key, key))
  105.                 return(p);
  106.             p = *p;
  107.             q=q->link;
  108.         }
  109.     }
  110.     return(0);
  111. }
  112.  
  113. SYM     *search(char *na,TABLE *table)
  114. {
  115.     SYM *thead = table->head;
  116.     SYM **p;
  117.     if (table == &gsyms) {
  118.         p=((SYM **)LookupHash(na,globalhash,HASHTABLESIZE));
  119.         if (p)
  120.             p = *p;
  121.         return (SYM *) p;
  122.     }
  123.     else if (table == &defsyms) {
  124.         p=((SYM **)LookupHash(na,defhash,HASHTABLESIZE));
  125.         if (p)
  126.             p = *p;
  127.         return (SYM *) p;
  128.     }
  129.     else
  130.            while( thead != 0) {
  131.                 if(strcmp(thead->name,na) == 0)
  132.                         return thead;
  133.                 thead = thead->next;
  134.                 }
  135.         return 0;
  136. }
  137.  
  138. SYM     *gsearch(char *na)
  139. {       SYM     *sp;
  140.         if( (sp = search(na,&lsyms)) == 0)
  141.                 sp = search(na,&gsyms);
  142.         return sp;
  143. }
  144.  
  145. void insert(SYM *sp,TABLE *table)
  146.  
  147. {
  148.     if (table == &gsyms) {
  149.         if (AddHash(sp,globalhash,HASHTABLESIZE))
  150.             gensymerror(ERR_DUPSYM,sp->name);
  151.     }
  152.   else if (table == &defsyms) {
  153.         AddHash(sp,defhash,HASHTABLESIZE);
  154.     }
  155.     else if (table == &lsyms) {
  156.         SYM *thead = table->head,*qhead = 0;
  157.         /* Only check the current local block... */
  158.       while( thead != oldlsym.head) {
  159.         if(strcmp(thead->name,sp->name) == 0) {
  160.               qhead = thead;
  161.                              break;
  162.                     }    
  163.         thead = thead->next;
  164.         }
  165.         if (qhead) 
  166.        gensymerror(ERR_DUPSYM,sp->name);
  167.         else {
  168.         /* Putting local symbols in backwards */
  169.       if( table->head == 0) {
  170.         table->head = table->tail = sp;
  171.           sp->next = 0;
  172.             }
  173.       else    {
  174.                 sp->next = table->head;
  175.                 table->head = sp;
  176.       }
  177.         }
  178.     }
  179.     else if( search(sp->name,table) == 0) {
  180.                 if( table->head == 0)
  181.                         table->head = table->tail = sp;
  182.                 else    {
  183.                         table->tail->next = sp;
  184.                         table->tail = sp;
  185.                         }
  186.                 sp->next = 0;
  187.                 }
  188.         else
  189.                 gensymerror(ERR_DUPSYM,sp->name);
  190. }
  191. TABLE *classsearch(char *class)
  192. {
  193.     char buf[30];
  194.     int i = 0;
  195.     buf[i++] = '_';
  196.     while (*class && *class != '@')
  197.         buf[i++] = *class++;
  198.     if ((sp = gsearch(buf)) == 0)
  199.         return 0;
  200.     while (TRUE) {
  201.         if (!*class++)
  202.             return &sp->tp.lst;
  203.         i = 0;
  204.         buf[i++] = '_';
  205.         while (*class && *class != '@')
  206.             buf[i++] = *class++;
  207.         if ((sp = search(buf,&sp->tp.lst)) == 0)
  208.             return 0;
  209.     }
  210. }
  211. void funcrefinsert(char *name, char *mangname, TYP *tp, TABLE *tbl)
  212. {
  213.     char buf[100];
  214.     SYM *sp,*sp1;
  215.     sp = xalloc(sizeof(SYM));
  216.     buf[0] = '$';
  217.     buf[1] = '$';
  218.     strcpy(&buf[2],name);
  219.     sp->defalt = mangname;
  220.     sp->storage_class = sc_defunc;
  221.     sp->value.overlist.head = 0;
  222.     sp->name = litlate(buf);
  223.     sp->tp = tp;
  224.     sp1 = search(buf,tbl);
  225.     if (sp1)
  226.         if (sp1->value.overlist.head == 0)
  227.             sp1->value.overlist.head = sp1->value.overlist.tail = sp;
  228.         else
  229.             sp1->value.overlist.tail = sp1->value.overlist.tail->next = sp;
  230.     else
  231.         insert(sp,tbl);
  232. }
  233. static int fomatch(TYP *tp1, TYP *tp2)
  234. {
  235.     SYM *sp1 = tp1->lst.head;
  236.     SYM *sp2 = tp2->lst.head;
  237.     if (sp1 == (SYM *)-1 && sp2 == (SYM *)-1)
  238.         return TRUE;
  239.     if (sp1 && sp1->defalt)
  240.         return TRUE;
  241.     while (sp2 && sp1) {
  242.         if (sp1->tp->type == bt_ellipse)
  243.             return TRUE;
  244.         if (!exactype(sp1->tp, sp2->tp) && !(isscalar(tp1) && isscalar(tp2)))
  245.             return FALSE;
  246.         sp1 = sp1->next;
  247.         sp2 = sp2->next;
  248.         if (sp1->defalt)
  249.             return TRUE;
  250.     }
  251.     return sp1 == sp2;
  252. }
  253. SYM *funcovermatch(char *name,char *class,TYP *tp)
  254. {
  255.     char *buf,buf1[100];
  256.     TABLE *tbl1, *tbl2;
  257.     if (prm_cplusplus) {
  258.         SYM *sp2,*sp3,*sp4=0,*sp5=0,*sp6,*sp7;
  259.         buf = cppmangle(name,class,tp);
  260.         if (class) {
  261.             tbl2 = 0;
  262.             tbl1 = classearch(class);
  263.         }
  264.         else {
  265.             tbl1 = lsyms;
  266.             tbl2 = gsyms;
  267.         }
  268.         buf1[0] = '$';
  269.         buf1[1] = '$';
  270.         strcpy(&buf1[2],name);
  271.         sp2 = search(buf1,&tbl1);
  272.         sp3 = search(buf1,&tbl2);
  273.         if (sp2)
  274.             if (fomatch(sp2->tp,tp)) 
  275.                 sp4 = sp2;
  276.         if (sp3)
  277.             if (fomatch(sp3->tp,tp)) 
  278.                 sp5 = sp3;
  279.         if (sp4 && sp5) {
  280.             genfunc2error(ERR_AMBIGFUNC,sp4->defalt,sp5->defalt);
  281.             return gsearch(sp4->defalt);
  282.         }
  283.         if (sp2) {
  284.             sp6 = sp2->value.overlist.head;
  285.             while (sp6) {
  286.                 if (fomatch(sp6->tp,tp)) {
  287.                     if (sp4) {
  288.                         genfunc2error(ERR_AMBIGFUNC,sp4->defalt,sp6->defalt);
  289.                         return gsearch(sp4->defalt);
  290.                     }
  291.                     else if (sp5) {
  292.                         genfunc2error(ERR_AMBIGFUNC,sp5->defalt,sp6->defalt);
  293.                         return gsearch(sp5->defalt);
  294.                     }
  295.                     else sp4 = sp6;
  296.                 }
  297.                 sp6 = sp6->next;
  298.             }
  299.         }
  300.         if (sp3) {
  301.             sp7 = sp3->value.overlist.head;
  302.             while (sp7) {
  303.                 if (fomatch(sp7->tp,tp)) {
  304.                     if (sp4) {
  305.                         genfunc2error(ERR_AMBIGFUNC,sp4->defalt,sp7->defalt);
  306.                         return gsearch(sp4->defalt);
  307.                     }
  308.                     else if (sp5) {
  309.                         genfunc2error(ERR_AMBIGFUNC,sp5->defalt,sp7->defalt);
  310.                         return gsearch(sp5->defalt);
  311.                     }
  312.                     else sp5 = sp7;
  313.                 }
  314.                 sp7 = sp7->next;
  315.             }
  316.         }
  317.         if (sp4)
  318.             return gsearch(sp4->defalt);
  319.         if (sp5)
  320.             return gsearch(sp5->defalt);
  321.     }
  322.     return(gsearch(name));
  323. }
  324. static char *cpponearg(char *buf,TYP *tp)
  325. {
  326. start:
  327.     switch (tp->type) {
  328.         case bt_ptrfunc:
  329.             *buf++ = 'q';
  330.             buf = cppargs(buf,tp->lst.head);
  331.             *buf++ = '$';
  332.             tp = tp->btp;
  333.             goto start;
  334.         case bt_struct:
  335.         case bt_union:
  336.         case bt_class:
  337.         case bt_enum:
  338.             sprintf(buf,"%d%s",strlen(tp->sname+1),tp->sname+1);
  339.             buf = buf + strlen(buf);
  340.             break;
  341.         case bt_unsignedshort:
  342.             *buf++ = 'u';
  343.         case bt_short:
  344.             *buf++ = 's';
  345.             break;
  346.         case bt_unsigned:
  347.             *buf++ = 'u';
  348.         case bt_long:
  349.             *buf++ = 'i';
  350.             break;
  351.         case bt_unsignedchar:
  352.             *buf++ = 'u';
  353.         case bt_char:
  354.             *buf++ = 'c';
  355.             break;
  356.         case bt_float:
  357.             *buf++ = 'f';
  358.             break;
  359.         case bt_double:
  360.             *buf++ = 'd';
  361.             break;
  362.         case bt_longdouble:
  363.             *buf++ = 'g';
  364.             break;
  365.         case bt_pointer:
  366.             *buf++ = 'p';
  367.             tp = tp->btp;
  368.             goto start;
  369.         case bt_ref:
  370.             *buf++ = 'r';
  371.             tp = tp->btp;
  372.             goto start;
  373.         case bt_ellipse:
  374.             *buf++ = 'e';
  375.             break;
  376.     }
  377.     *buf = 0;
  378.     return buf;
  379. }
  380. static char *cppargs(char *buf,SYM *sp)
  381. {
  382.     *buf++ = 'q';
  383.     if (sp == (SYM *)-1) {
  384.         *buf++ = 'v';
  385.     }
  386.     else while (sp) {
  387.         buf = cpponearg(buf,sp->tp);
  388.         sp = sp->next;
  389.     }
  390.     *buf=0;
  391.     return buf + strlen(buf);
  392. }
  393.     
  394. char * cppmangle(char *name, char *class,  TYP *tp)
  395. {
  396.     char buf[100],*p = strrchr(class,'@');
  397.     if (*name == 0)
  398.         return 0;
  399.     if (prm_cmangle)
  400.         name++;
  401.     if (!p)
  402.         goto join;
  403.     p++;
  404.     if (!strcmp(cp,name))
  405.         sprintf(buf,"@%s$",constructor_name);
  406.     else if (!strcmp(p,name+1) && name[0] == '~')
  407.         sprintf(buf,"@%s$",destructor_name);
  408.     else {
  409. join:
  410.         sprintf(buf,"@%s$",name);
  411.     }
  412.     cppargs(buf+strlen(buf),tp->lst.head);
  413.     return(litlate(buf));
  414. }
  415.     
  416. char * putptr(char *buf, int *ptr, int **ptrs)
  417. {
  418.     int *p = *ptrs;
  419.     buf = buf+strlen(buf);
  420.     while ((*ptr)--) {
  421.         *buf++ = ' ';
  422.         if (*p++) 
  423.             *buf++= '&';
  424.         else
  425.             *buf++ = '*';
  426.     }
  427.     *ptr = 0;
  428.     *buf = 0;
  429.     return buf;
  430. }            
  431.             
  432. static char *unmang1(char *buf, char *name, int *ptr, int **ptrs)
  433. {
  434. start:
  435.         if (isdigit(*name)) {
  436.             int v = *name++ - '0';
  437.             while (isdigit(*name)) 
  438.                 v = v*10+ *name++ - '0';
  439.             while (v--) 
  440.                 *buf++ = *name++;
  441.             *buf = 0;
  442.         }
  443.         else switch (*name++) {
  444.             case 'q': {
  445.                     char buf1[100],buf2[100];
  446.                     strcpy(buf1," (*) ");
  447.                     buf+=5;
  448.                   name = unmangcppfunc(buf1,name);
  449.                     name++;
  450.                     name = unmang1(buf2,name,ptr,ptrs);
  451.                     buf = putptr(buf,ptr,ptrs);
  452.                     strcpy(buf,buf2);
  453.                     strcat(buf,buf1);
  454.                     buf = buf +strlen(buf);
  455.                     
  456.                 }
  457.                 break;    
  458.             case 'u':
  459.                 strcpy(buf,"unsigned ");
  460.                 buf = buf+9;
  461.                 switch(*name++) {
  462.                     case 'i':
  463.                         strcpy(buf,tn_int);
  464.                         buf = putptr(buf,ptr,ptrs);
  465.                         break;
  466.                     case 'l':
  467.                         strcpy(buf,tn_long);
  468.                         buf = putptr(buf,ptr,ptrs);
  469.                         break;
  470.                     case 's':
  471.                         strcpy(buf,tn_short);
  472.                         buf = putptr(buf,ptr,ptrs);
  473.                         break;
  474.                     case 'c':
  475.                         strcpy(buf,tn_char);
  476.                         buf = putptr(buf,ptr,ptrs);
  477.                         break;
  478.                 }
  479.             case 'f':
  480.                 strcpy(buf,tn_float);
  481.                 buf = putptr(buf,ptr,ptrs);
  482.                 break;
  483.             case 'd':
  484.                 strcpy(buf,tn_double);
  485.                 buf = putptr(buf,ptr,ptrs);
  486.                 break;
  487.             case 'g':
  488.                 strcpy(buf,tn_longdouble);
  489.                 buf = putptr(buf,ptr,ptrs);
  490.                 break;
  491.             case 'i':
  492.                 strcpy(buf,tn_int);
  493.                 buf = putptr(buf,ptr,ptrs);
  494.                 break;
  495.             case 'l':
  496.                 strcpy(buf,tn_long);
  497.                 buf = putptr(buf,ptr,ptrs);
  498.                 break;
  499.             case 's':
  500.                 strcpy(buf,tn_short);
  501.                 buf = putptr(buf,ptr,ptrs);
  502.                 break;
  503.             case 'c':
  504.                 strcpy(buf,tn_char);
  505.                 buf = putptr(buf,ptr,ptrs);
  506.                 break;
  507.             case 'v':
  508.                 strcpy(buf,tn_void);
  509.                 buf = putptr(buf,ptr,ptrs);
  510.                 break;
  511.             case 'p':
  512.                 (*ptrs)[(*ptr)++] = 0;
  513.                 goto start;
  514.             case 'r':
  515.                 (*ptrs)[(*ptr)++] = 1;
  516.                 goto start;
  517.             case 'e':
  518.                 strcpy(buf,tn_ellipse);
  519.                 break;
  520.             case '$':
  521.                 name--;
  522.                 return name;
  523.         }
  524.     return name;
  525. }
  526. static char * unmangcppfunc(char *buf, char *name)
  527. {
  528.     int ptr = 0;
  529.     char ptrs[50];
  530.     *buf++ = '(';
  531.     while (*name && *name != '$') {
  532.         name = unmang1(buf,name,&ptr,&ptrs);
  533.         buf = buf+strlen(buf);
  534.         if (*name && *name != '$')
  535.             *buf++ = ',';
  536.         else
  537.             *buf++ = ')';
  538.     }
  539.     *buf=0;
  540.     return buf;
  541. }
  542. void unmangle(char *buf, char *name,char *class)
  543. {
  544.     if (name[0] == '_') {
  545.         strcpy(buf,&name[1]);
  546.     }
  547.     else 
  548.         if (name[0] != '@')
  549.             strcpy(buf,name);
  550.         else {
  551.             name++;
  552.             if (class) {
  553.                 *buf = 0;
  554.                 if (!strcmp(name,constructor_name)) {
  555.                     strcpy(buf,class);
  556.                     buf+=strlen(buf);
  557.                 }
  558.                 else if (!strcmp(name,destructor_name)) {
  559.                     sprintf(buf,"~%s",class);
  560.                     buf+=strlen(buf);
  561.                 }
  562.                 else 
  563.                     while (*name != '$' && *name)
  564.                         *buf++ = *name++;
  565.             }
  566.             else while (*name != '$' && *name)
  567.                 *buf++ = *name++;
  568.             if (*name) {
  569.                 name+=2;
  570.                 unmangcppfunc(buf,name);
  571.             }
  572.             else *buf++ = 0;
  573.         }
  574. }