C:/Users/Dennis/src/lang/russell.orig/src/pass3/tsig_order.c

Go to the documentation of this file.
00001 # define DEBUG
00002 # include "parm.h"
00003 
00004 # include "stree/ststructs.mh"
00005 
00006 # include "stree/Array.h"
00007 
00008 # include "pass4/sigs.h"
00009 
00010 int comp_tsc();             /* comparison routine for sorting         */
00011 
00012 void add_dcse();            /* Add to the exception list of the default */
00013                             /* character signature list                 */
00014 
00015 static NODE * type_sig;     /* copy of parameter to tsig_order        */
00016                             /* used by comp_tsc                       */ 
00017 
00018 char * getname();
00019 
00020 /*
00021  *  tsig_order(type_signature)
00022  *
00023  *  Rearrange the type_signature in the canonical order given
00024  * in the WHAT file.
00025  */
00026 
00027 void tsig_order(tsig)
00028 NODE * tsig;
00029 {
00030     Array * a;  /* array representation of the type signature */
00031     int a_len;  /* number of pointers in a */
00032     NODE * constants;   /* pointer to composite DEFCHARSIGS node being built */
00033     register int i,j;
00034     unsigned *p, *q;
00035     NODE * r;
00036 
00037     a = list_to_array(tsig -> ts_clist);
00038     a_len = a->a_size;
00039 
00040 
00041     constants = lock(mknode(DEFCHARSIGS,0,0,0,0));
00042     /* build constants node */
00043         for(i = 0; i < a_len; i++) {
00044             if (a->a_body[i] -> kind == DEFCHARSIGS) {
00045                 p = &(a->a_body[i] -> dcs_0);
00046                 q = &(constants -> dcs_0);
00047                 for (j = 0; j < NVECTORS; j++) {
00048                     *q++ |= *p++;
00049                 }
00050                 /* Cancel the node in the array */
00051                     unlock(a->a_body[i]);
00052                     a->a_body[i] = NIL;
00053             } else {
00054                 register NODE * csig;    /* signature of component */
00055 
00056 #               ifdef DEBUG
00057                     if(a->a_body[i] -> kind != TSCOMPONENT) {
00058                         dbgmsg("tsig_order: bad tsig component\n");
00059                     }
00060 #               endif
00061                 csig = a->a_body[i] -> tsc_signature;
00062 #               ifdef DEBUG
00063                     if(csig -> kind != FUNCSIGNATURE &&
00064                        csig -> kind != TYPESIGNATURE &&
00065                        csig -> kind != VALSIGNATURE) {
00066                         dbgmsg("tsig_order: bad tsc sig, kind = %s\n",
00067                                kindname(csig -> kind));
00068                         abort(a->a_body[i],csig);
00069                     }
00070 #               endif
00071                 if ( is_const(csig, tsig) ) {
00072                     char * nm 
00073                          = getname(a->a_body[i] -> tsc_id -> id_str_table_index);
00074 
00075                     if ( nm[0] == '\'' && nm[2] == '\'' ) {
00076                         /* This is a constant */
00077                         unsigned *word;
00078                         int bitno;
00079                         char character = nm[1];
00080                         int wordno = ((int) character) / WORDLENGTH;
00081 
00082                         word = (&(constants -> dcs_0) + wordno);
00083                         bitno = ((int) character) - wordno * WORDLENGTH;
00084                         *word |= 1 << (WORDLENGTH - bitno - 1);
00085                         /* cancel array entry */
00086                             unlock(a->a_body[i]);
00087                             a->a_body[i] = NIL;
00088                         if (special_tp(csig -> fsig_special) != NOT_SPECIAL
00089                             || csig -> fsig_inline_code != NIL
00090                             || csig -> fsig_construction != NIL) {
00091                             if (constants -> dcs_exceptions == NIL) {
00092                                 initfld(&(constants -> dcs_exceptions), emptylist());
00093                             }
00094                             add_dcse(constants -> dcs_exceptions, character,
00095                                      csig -> fsig_inline_code,
00096                                      csig -> fsig_special,
00097                                      csig -> fsig_construction);
00098                         }
00099                     }
00100                 }
00101             }
00102         }
00103 
00104     /* Remove all NIL array entries */
00105         i = 0;  /* next location to be copied into */
00106         for(j = 0; j < a_len; j++) {
00107             if(a->a_body[j] != NIL) {
00108                 r = a->a_body[j];
00109                 /* Clear old location so reference counts dont get */
00110                 /* messed up.                                      */
00111                     a->a_body[j] = NIL;
00112                 a->a_body[i++] = r;
00113             }
00114         }
00115         a_len = i;
00116 
00117 
00118     /* Sort the remaining array */
00119         type_sig = tsig;
00120         qsort(&a->a_body[0], a_len, (sizeof (NODE *)), comp_tsc);
00121 
00122 
00123     /* Put everything back into the type signature node */
00124         chgfld(&(tsig -> ts_clist), mklist(constants,-1));
00125         for (i = 0; i < a_len; i++) {
00126             addright(tsig -> ts_clist, a->a_body[i]);
00127         }
00128         free_array(a);
00129 }
00130 
00131 
00132 /* compare 2 TSCOMPONENT structures */
00133 int comp_tsc(p, q)
00134 NODE **p, **q;
00135 
00136 {
00137     register int i;
00138     i =  strcmp(getname((*p) -> tsc_id -> id_str_table_index),
00139                 getname((*q) -> tsc_id -> id_str_table_index));
00140     if (i == 0)
00141         return(comp_st((*p) -> tsc_signature, (*q) -> tsc_signature,
00142                        type_sig, type_sig));
00143     else
00144         return(i);
00145 }
00146 
00147 /* 
00148  *  is_const(sig,tsig)
00149  *  returns TRUE iff sig has the form
00150  *  func[] val local_type_id and if it is not special.
00151  *  (It is unsafe to lose special information, e.g. in enum constructions.
00152  *  Thus we check for its presence.  Special constants are never part
00153  *  of strings compiled with in-line code.  Thus this shouldn't matter.)
00154  */
00155 
00156 boolean is_const(sig,tsig)
00157 NODE * sig, * tsig;
00158 {
00159 
00160     if(sig == NIL) return(FALSE);
00161     if(sig -> kind == FUNCSIGNATURE
00162        && is_empty(sig -> fsig_param_list)
00163        && sig -> fsig_result_sig != ERR_SIG
00164        && sig -> fsig_result_sig -> kind == VALSIGNATURE) {
00165             NODE * tden = sig -> fsig_result_sig -> val_denotation;
00166 
00167             if( (tden->kind == LETTERID || tden->kind == OPRID)
00168                  && (tden -> id_str_table_index == -1
00169                      || tden -> id_last_definition == tsig)) {
00170                 return(TRUE);
00171             }
00172 
00173     }
00174     if((sig -> kind == LETTERID || sig -> kind == OPRID)
00175        && sig -> id_last_definition != NIL
00176        && sig -> id_last_definition -> kind == DECLARATION
00177        && sig -> id_last_definition -> decl_sig_transp
00178        && sig -> id_last_definition -> post_num < sig -> post_num) {
00179         return(is_const(sig -> id_last_definition -> decl_denotation));
00180     }
00181     return(FALSE);
00182 }
00183 
00184 /* 
00185  *  Add an exception with the given character, in-line code, special, and
00186  * construction fields to the character constant eception list l.
00187  * This is a DESTRUCTIVE operation.
00188  */
00189 void add_dcse(l, character, in_line, spcl, construction)
00190 NODE *l;
00191 int character;
00192 char *in_line;
00193 int spcl;
00194 NODE *construction;
00195 {
00196     NODE * new_node = mknode(DCSEXCEPTION);
00197 
00198 #   ifdef DEBUG
00199         if (l -> kind != LISTHEADER
00200             || (!is_empty(l) && (first(l)) -> kind != DCSEXCEPTION) ) {
00201             dbgmsg("add_dcse: bad exception list\n");
00202         }
00203 #   endif
00204     new_node -> dcse_char = character;
00205     new_node -> dcse_inline = in_line;
00206     new_node -> dcse_special = spcl;
00207     new_node -> dcse_construction = construction;
00208     mapinslist(s, l, {
00209         if (s == NIL || s -> dcse_char > character) {
00210             INSERT(new_node);
00211             break;
00212         } else if (s -> dcse_char == character) {
00213             /* Entries are never deleted.  Thus there could still be an */
00214             /* obsolete entry for the same character.                   */
00215             REPLACE(new_node);
00216             break;
00217         }
00218     });
00219 }

Generated on Fri Jan 25 10:39:46 2008 for russell by  doxygen 1.5.4