home *** CD-ROM | disk | FTP | other *** search
/ CD Shareware Magazine 1996 December / CD_shareware_12-96.iso / DOS / Programa / CCDL122.ZIP / SOURCE / SYMBOL.C < prev    next >
Encoding:
C/C++ Source or Header  |  1996-08-06  |  11.3 KB  |  523 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. void funcrefinsert(char *name, char *mangname, TYP *tp, TABLE *tbl)
  192. {
  193.     char buf[100];
  194.     SYM *sp,*sp1;
  195.     sp = xalloc(sizeof(SYM));
  196.     buf[0] = '$';
  197.     buf[1] = '$';
  198.     strcpy(&buf[2],name);
  199.     sp->defalt = mangname;
  200.     sp->storage_class = sc_defunc;
  201.     sp->value.overlist.head = 0;
  202.     sp->name = litlate(buf);
  203.     sp->tp = tp;
  204.     sp1 = search(buf,tbl);
  205.     if (sp1)
  206.         if (sp1->value.overlist.head == 0)
  207.             sp1->value.overlist.head = sp1->value.overlist.tail = sp;
  208.         else
  209.             sp1->value.overlist.tail = sp1->value.overlist.tail->next = sp;
  210.     else
  211.         insert(sp,tbl);
  212. }
  213. static int fomatch(TYP *tp1, TYP *tp2)
  214. {
  215.     SYM *sp1 = tp1->lst.head;
  216.     SYM *sp2 = tp2->lst.head;
  217.     if (sp1 == (SYM *)-1 && sp2 == (SYM *)-1)
  218.         return TRUE;
  219.     if (sp1 && sp1->defalt)
  220.         return TRUE;
  221.     while (sp2 && sp1) {
  222.         if (sp1->tp->type == bt_ellipse)
  223.             return TRUE;
  224.         if (!exactype(sp1->tp, sp2->tp) && !(isscalar(tp1) && isscalar(tp2)))
  225.             return FALSE;
  226.         if (sp1->defalt)
  227.             return TRUE;
  228.         sp1 = sp1->next;
  229.         sp2 = sp2->next;
  230.     }
  231.     return sp1 == sp2;
  232. }
  233. SYM *funcovermatch(char *name,TYP *tp)
  234. {
  235.     char buf1[100];
  236.     TABLE *tbl1, *tbl2;
  237.     if (prm_cplusplus) {
  238.         SYM *sp2,*sp3,*sp4=0,*sp5=0,*sp6,*sp7;
  239.         tbl1 = &lsyms;
  240.         tbl2 = &gsyms;
  241.         buf1[0] = '$';
  242.         buf1[1] = '$';
  243.         strcpy(&buf1[2],name);
  244.         sp2 = search(buf1,tbl1);
  245.         sp3 = search(buf1,tbl2);
  246.         if (sp2)
  247.             if (fomatch(sp2->tp,tp)) 
  248.                 sp4 = sp2;
  249.         if (sp3)
  250.             if (fomatch(sp3->tp,tp)) 
  251.                 sp5 = sp3;
  252.         if (sp4 && sp5) {
  253.             genfunc2error(ERR_AMBIGFUNC,sp4->defalt,sp5->defalt);
  254.             return gsearch(sp4->defalt);
  255.         }
  256.         if (sp2) {
  257.             sp6 = sp2->value.overlist.head;
  258.             while (sp6) {
  259.                 if (fomatch(sp6->tp,tp)) {
  260.                     if (sp4) {
  261.                         genfunc2error(ERR_AMBIGFUNC,sp4->defalt,sp6->defalt);
  262.                         return gsearch(sp4->defalt);
  263.                     }
  264.                     else if (sp5) {
  265.                         genfunc2error(ERR_AMBIGFUNC,sp5->defalt,sp6->defalt);
  266.                         return gsearch(sp5->defalt);
  267.                     }
  268.                     else sp4 = sp6;
  269.                 }
  270.                 sp6 = sp6->next;
  271.             }
  272.         }
  273.         if (sp3) {
  274.             sp7 = sp3->value.overlist.head;
  275.             while (sp7) {
  276.                 if (fomatch(sp7->tp,tp)) {
  277.                     if (sp4) {
  278.                         genfunc2error(ERR_AMBIGFUNC,sp4->defalt,sp7->defalt);
  279.                         return gsearch(sp4->defalt);
  280.                     }
  281.                     else if (sp5) {
  282.                         genfunc2error(ERR_AMBIGFUNC,sp5->defalt,sp7->defalt);
  283.                         return gsearch(sp5->defalt);
  284.                     }
  285.                     else sp5 = sp7;
  286.                 }
  287.                 sp7 = sp7->next;
  288.             }
  289.         }
  290.         if (sp4)
  291.             return gsearch(sp4->defalt);
  292.         if (sp5)
  293.             return gsearch(sp5->defalt);
  294.     }
  295.     return(gsearch(name));
  296. }
  297. static char *cpponearg(char *buf,TYP *tp)
  298. {
  299. start:
  300.     switch (tp->type) {
  301.         case bt_ptrfunc:
  302.             *buf++ = 'q';
  303.             buf = cppargs(buf,tp->lst.head);
  304.             *buf++ = '$';
  305.             tp = tp->btp;
  306.             goto start;
  307.         case bt_struct:
  308.         case bt_union:
  309.         case bt_class:
  310.         case bt_enum:
  311.             sprintf(buf,"%d%s",strlen(tp->sname+1),tp->sname+1);
  312.             buf = buf + strlen(buf);
  313.             break;
  314.         case bt_unsignedshort:
  315.             *buf++ = 'u';
  316.         case bt_short:
  317.             *buf++ = 's';
  318.             break;
  319.         case bt_unsigned:
  320.             *buf++ = 'u';
  321.         case bt_long:
  322.             *buf++ = 'i';
  323.             break;
  324.         case bt_unsignedchar:
  325.             *buf++ = 'u';
  326.         case bt_char:
  327.             *buf++ = 'c';
  328.             break;
  329.         case bt_float:
  330.             *buf++ = 'f';
  331.             break;
  332.         case bt_double:
  333.             *buf++ = 'd';
  334.             break;
  335.         case bt_longdouble:
  336.             *buf++ = 'g';
  337.             break;
  338.         case bt_pointer:
  339.             *buf++ = 'p';
  340.             tp = tp->btp;
  341.             goto start;
  342.         case bt_ref:
  343.             *buf++ = 'r';
  344.             tp = tp->btp;
  345.             goto start;
  346.         case bt_ellipse:
  347.             *buf++ = 'e';
  348.             break;
  349.     }
  350.     *buf = 0;
  351.     return buf;
  352. }
  353. static char *cppargs(char *buf,SYM *sp)
  354. {
  355.     *buf++ = 'q';
  356.     if (sp == (SYM *)-1) {
  357.         *buf++ = 'v';
  358.     }
  359.     else while (sp) {
  360.         buf = cpponearg(buf,sp->tp);
  361.         sp = sp->next;
  362.     }
  363.     *buf=0;
  364.     return buf + strlen(buf);
  365. }
  366.     
  367. char * cppmangle(char *name, TYP *tp)
  368. {
  369.     char buf[100];
  370.     if (*name == 0)
  371.         return 0;
  372.     if (prm_cmangle)
  373.         name++;
  374.     sprintf(buf,"@%s$",name);
  375.     cppargs(buf+strlen(buf),tp->lst.head);
  376.     return(litlate(buf));
  377. }
  378.     
  379. char * putptr(char *buf, int *ptr, int **ptrs)
  380. {
  381.     int *p = *ptrs;
  382.     buf = buf+strlen(buf);
  383.     while ((*ptr)--) {
  384.         *buf++ = ' ';
  385.         if (*p++) 
  386.             *buf++= '&';
  387.         else
  388.             *buf++ = '*';
  389.     }
  390.     *ptr = 0;
  391.     *buf = 0;
  392.     return buf;
  393. }            
  394.             
  395. static char *unmang1(char *buf, char *name, int *ptr, int **ptrs)
  396. {
  397. start:
  398.         if (isdigit(*name)) {
  399.             int v = *name++ - '0';
  400.             while (isdigit(*name)) 
  401.                 v = v*10+ *name++ - '0';
  402.             while (v--) 
  403.                 *buf++ = *name++;
  404.             *buf = 0;
  405.         }
  406.         else switch (*name++) {
  407.             case 'q': {
  408.                     char buf1[100],buf2[100];
  409.                     strcpy(buf1," (*) ");
  410.                     buf+=5;
  411.                   name = unmangcppfunc(buf1,name);
  412.                     name++;
  413.                     name = unmang1(buf2,name,ptr,ptrs);
  414.                     buf = putptr(buf,ptr,ptrs);
  415.                     strcpy(buf,buf2);
  416.                     strcat(buf,buf1);
  417.                     buf = buf +strlen(buf);
  418.                     
  419.                 }
  420.                 break;    
  421.             case 'u':
  422.                 strcpy(buf,"unsigned ");
  423.                 buf = buf+9;
  424.                 switch(*name++) {
  425.                     case 'i':
  426.                         strcpy(buf,tn_int);
  427.                         buf = putptr(buf,ptr,ptrs);
  428.                         break;
  429.                     case 'l':
  430.                         strcpy(buf,tn_long);
  431.                         buf = putptr(buf,ptr,ptrs);
  432.                         break;
  433.                     case 's':
  434.                         strcpy(buf,tn_short);
  435.                         buf = putptr(buf,ptr,ptrs);
  436.                         break;
  437.                     case 'c':
  438.                         strcpy(buf,tn_char);
  439.                         buf = putptr(buf,ptr,ptrs);
  440.                         break;
  441.                 }
  442.             case 'f':
  443.                 strcpy(buf,tn_float);
  444.                 buf = putptr(buf,ptr,ptrs);
  445.                 break;
  446.             case 'd':
  447.                 strcpy(buf,tn_double);
  448.                 buf = putptr(buf,ptr,ptrs);
  449.                 break;
  450.             case 'g':
  451.                 strcpy(buf,tn_longdouble);
  452.                 buf = putptr(buf,ptr,ptrs);
  453.                 break;
  454.             case 'i':
  455.                 strcpy(buf,tn_int);
  456.                 buf = putptr(buf,ptr,ptrs);
  457.                 break;
  458.             case 'l':
  459.                 strcpy(buf,tn_long);
  460.                 buf = putptr(buf,ptr,ptrs);
  461.                 break;
  462.             case 's':
  463.                 strcpy(buf,tn_short);
  464.                 buf = putptr(buf,ptr,ptrs);
  465.                 break;
  466.             case 'c':
  467.                 strcpy(buf,tn_char);
  468.                 buf = putptr(buf,ptr,ptrs);
  469.                 break;
  470.             case 'v':
  471.                 strcpy(buf,tn_void);
  472.                 buf = putptr(buf,ptr,ptrs);
  473.                 break;
  474.             case 'p':
  475.                 (*ptrs)[(*ptr)++] = 0;
  476.                 goto start;
  477.             case 'r':
  478.                 (*ptrs)[(*ptr)++] = 1;
  479.                 goto start;
  480.             case 'e':
  481.                 strcpy(buf,tn_ellipse);
  482.                 break;
  483.             case '$':
  484.                 name--;
  485.                 return name;
  486.         }
  487.     return name;
  488. }
  489. static char * unmangcppfunc(char *buf, char *name)
  490. {
  491.     int ptr = 0;
  492.     char ptrs[50];
  493.     *buf++ = '(';
  494.     while (*name && *name != '$') {
  495.         name = unmang1(buf,name,&ptr,&ptrs);
  496.         buf = buf+strlen(buf);
  497.         if (*name && *name != '$')
  498.             *buf++ = ',';
  499.         else
  500.             *buf++ = ')';
  501.     }
  502.     *buf=0;
  503.     return buf;
  504. }
  505. void unmangle(char *buf, char *name)
  506. {
  507.     if (name[0] == '_') {
  508.         strcpy(buf,&name[1]);
  509.     }
  510.     else 
  511.         if (name[0] != '@')
  512.             strcpy(buf,name);
  513.         else {
  514.             name++;
  515.             while (*name != '$' && *name)
  516.                 *buf++ = *name++;
  517.             if (*name) {
  518.                 name+=2;
  519.                 unmangcppfunc(buf,name);
  520.             }
  521.             else *buf++ = 0;
  522.         }
  523. }