C:/Users/Dennis/src/lang/russell.orig/src/pass4/getcomp.c

Go to the documentation of this file.
00001 # define DEBUG
00002 
00003 # ifdef DEBUG
00004 #   define IFDEBUG(x) x
00005 # else
00006 #   define IFDEBUG(x)
00007 # endif
00008 
00009 # include <stdio.h>
00010 # include "parm.h"
00011 
00012 # include "stree/ststructs.mh"
00013 
00014 # include "pass3/decl_pairs.h"
00015 
00016 char * (* inline_cnvt)();
00017 
00018 char * getname();
00019 
00020 extern unsigned indx_subscr; /*DEBUG*/
00021 
00022 extern int stplinks[];
00023 
00024 extern int stsize[];
00025 
00026 extern int stsigs[];
00027 
00028 extern int yynerrs;  /* number of errors encountered in this pass */
00029 
00030 # include "pass3/is_local.h"
00031 # include "sigs.h"
00032 
00033 int comp_index;
00034 
00035 extern FILE * unparse_file;
00036 
00037 NODE * tsubst();
00038 
00039 extern NODE * sig_const;
00040 
00041 /*
00042  *  getcomp(type_signature, id_node, type_expression,
00043  *          component_signature, enclosing_type, application, exact)
00044  * 
00045  *  Returns the signature of the component of the type_signature which
00046  * is pointed to by the second parameter (NIL if there is none).
00047  *  Either a signature or an application may be given to resolve
00048  * overloading.  Exact specifies whether argument signatures must
00049  * match exactly, i.e. whether coercions are allowed.
00050  *  The type expression (if any) is substituted for the local type identifier.
00051  * (The component_signature is matched after the substitution.)
00052  *  If no substitution is performed, an enclosing type may be given
00053  * for the component signature.  The argument list is ignored in this case.
00054  *  comp_index is set to the index of the component in the type
00055  * signature.
00056  */
00057 
00058 
00059 NODE * getcomp(sig,id,exp,csig,ctype,appl,exact)
00060 NODE * sig, * exp;
00061 NODE * id;
00062 NODE * csig, * appl;
00063 boolean exact;
00064 {
00065     register NODE * p;
00066     register boolean is_char;
00067                             /* ind refers to a single character quoted id */
00068     char * name;            /* identifier name */
00069     char character;         /* identifier name (non-quote char) when      */
00070                             /* is_char is true.                           */
00071     NODE * exp_sig;         /* expanded signature of component            */
00072     int ci;                 /* local version of comp_index                */
00073     int ind = id -> id_str_table_index;
00074     int i;
00075 #   ifdef DEBUG
00076         boolean trace = FALSE;
00077 #   endif
00078 
00079     if (sig == ERR_SIG) return(ERR_SIG);
00080 #   ifdef DEBUG
00081 #     ifdef VAX
00082         if (nargs() != 7) {
00083             dbgmsg("getcomp: wrong number of args\n");
00084             abort();
00085         }
00086 #     endif
00087         if (sig -> kind != TYPESIGNATURE) {
00088             dbgmsg("getcomp: bad type signature\n");
00089             abort();
00090         }
00091         if (appl != NIL && appl -> kind != APPLICATION) {
00092             dbgmsg("getcomp: bad application\n");
00093         }
00094 #   endif
00095 
00096     ci = 0;
00097     name = getname(ind);
00098     if(is_char = (name[0] == '\'' && name[2] == '\'')) character = name[1];
00099 #   ifdef DEBUG
00100         if (trace) {
00101             unparse_file = stdout;
00102             printf("Looking in:\n");
00103             unparse(sig);
00104             printf ("\nname = %s, is_char = %d, character = %c, appl = %X\n",
00105                      name, is_char, character, appl);
00106         }
00107 #   endif
00108     begin_maplist(p, sig -> ts_clist) {
00109         if (p -> kind == TSCOMPONENT) {
00110             if (p -> tsc_id -> id_str_table_index == ind) {
00111 #               ifdef DEBUG
00112                   if (trace) {
00113                     printf("found matching id\n");
00114                   }
00115 #               endif
00116                 if (exp == NIL) {
00117 #                   ifdef DEBUG
00118                       if (trace) {
00119                         printf ("No type expression\n");
00120                         unparse_file = stdout;
00121                         printf("Actual component signature:\n");
00122                         unparse(p -> tsc_signature);
00123                         printf("\n");
00124                         printf("\nSpecified component signature:\n");
00125                         unparse(csig);
00126                         printf("\n");
00127                         printf("\ntype signature:\n");
00128                         unparse(sig);
00129                         printf("\nlocal id refers to:\n");
00130                         unparse(ctype);
00131                         printf("\n");
00132                       }
00133 #                   endif
00134                     if (csig == NIL
00135                         || comp_st(p -> tsc_signature,
00136                                    csig,
00137                                    sig,
00138                                    ctype) == 0) {
00139 #                       ifdef DEBUG
00140                             if (trace) {
00141                                 printf ("Found it\n");
00142                                 printf ("comp_index = %d\n", ci);
00143                             }
00144 #                       endif
00145                         comp_index = ci;
00146                         return(p -> tsc_signature);
00147                     } else {
00148 #                       ifdef DEBUG
00149                             if (trace) printf ("Failed signature comp\n");
00150 #                       endif
00151                         ci++;
00152                     }
00153                 } else {
00154                   /* do substitution and then check */
00155 #                   ifdef DEBUG
00156                         if (trace) {
00157                             printf ("Substituting %X for type %X\n", exp, sig);
00158                         }
00159 #                   endif
00160                     exp_sig = tsubst(p -> tsc_signature, sig, exp, TRUE);
00161 #                   ifdef DEBUG
00162                         if (trace) {
00163                             unparse_file = stdout;
00164                             printf("Type component signature:\n");
00165                             unparse(exp_sig);
00166                             printf("\nExpected signature:\n");
00167                             unparse(csig);
00168                             if (appl != NIL) {
00169                               printf("\nApplication:\n");
00170                               unparse(appl);
00171                               printf("\nargument signatures:\n");
00172                               maplist(s, appl -> ap_args, {
00173                                 printf(",");
00174                                 unparse(s -> signature);
00175                               });
00176                             }
00177                             printf("\n");
00178                         }
00179 #                   endif
00180                     if (def_match(exp_sig, csig, appl, id, exact)) {
00181 #                       ifdef DEBUG
00182                             if (trace) {
00183                                 printf ("Found it\n");
00184                                 printf ("comp_index = %d\n", ci);
00185                             }
00186 #                       endif
00187                         comp_index = ci;
00188                         return(exp_sig);
00189                     } else {
00190 #                       ifdef DEBUG
00191                             if (trace) printf ("Failed signature comp\n");
00192 #                       endif
00193                         ci++;
00194                     }
00195                 }
00196             } else {
00197                 ci++;
00198             }
00199         }
00200         /* Check whether it is a character with a default signature */
00201             if(p -> kind == DEFCHARSIGS) {
00202 
00203                 unsigned word;
00204                 int bitno;
00205                 int wordno;
00206                 unsigned * base = &(p -> dcs_0);
00207                 unsigned * s;
00208 
00209                 if (is_char) {
00210                     wordno = ((int) character) / WORDLENGTH;
00211                     word = *(base + wordno);
00212                     bitno = ((int) character) - wordno * WORDLENGTH;
00213                 }
00214 
00215                 if ( is_char && (((int) word) << bitno) < 0
00216                       && (exp == NIL ?
00217                             (exp_sig = sig_const, csig == NIL)
00218                             || (comp_st(sig_const, csig, sig, ctype) == 0)
00219                           : def_match(exp_sig = tsubst(sig_const,sig,exp,TRUE),
00220                                       csig, appl, id, exact)) )  {
00221                     /* type component appears in this node */
00222                     /* update comp_index                   */
00223                         for (s = base; s < base + wordno; s++){
00224                             ci += bitcnt(*s);
00225                         }
00226                         for (i = 0; i < bitno; i++) {
00227                             if ((((int) word) << i) < 0) 
00228                                 ci++;
00229                         }
00230                     if (sig -> ts_const_code != NIL) {
00231                         char *t;
00232                         NODE * s = exp_sig;
00233                         exp_sig = copynode(s);
00234                         vfree(s);
00235                         t = (char *)malloc(strlen(sig -> ts_const_code)+NINCR);
00236                         sprintf(t, sig -> ts_const_code, character, character);
00237                         exp_sig -> fsig_inline_code = (* inline_cnvt)(t);
00238                     } else if (p -> dcs_exceptions != NIL) {
00239                         /* See if this is an "exceptional" constant.  */
00240                         /* If so, update special and in_line fields   */
00241                         maplist(r, p -> dcs_exceptions, {
00242                             if (r -> dcse_char == character) {
00243                                 NODE * s = exp_sig;
00244                                 exp_sig = copynode(s);
00245                                 vfree(s);
00246                                 exp_sig -> fsig_inline_code = r -> dcse_inline;
00247                                 exp_sig -> fsig_special = r -> dcse_special;
00248                                 exp_sig -> fsig_construction = r -> dcse_construction;
00249                             } else if (r -> dcse_char > character) {
00250                                 break;
00251                             }
00252                         });
00253                     }
00254                     comp_index = ci;
00255                     return(exp_sig);
00256                 } else {
00257                     for (s = base; s < base + NVECTORS; s++) {
00258                         ci += bitcnt(*s);
00259                     }
00260                 }
00261             }
00262 #       ifdef DEBUG
00263             if(p -> kind != TSCOMPONENT && p -> kind != DEFCHARSIGS) {
00264                 dbgmsg("getcomp: bad tsc\n");
00265             }
00266 #       endif
00267     } end_maplist;
00268     /* no matching component */
00269     return(NIL);
00270 }
00271 
00272 
00273 /*
00274  * tsig_length(type_signature)
00275  *  
00276  * returns the number of components in a type signature, and thus the
00277  * length of the runtime representation of that type.  Like everything
00278  * else here it expects the signature to be normalized.
00279  */
00280 int
00281 tsig_length(tsig)
00282 NODE * tsig;
00283 {
00284     int result = 0;
00285     NODE * p;
00286     unsigned * base, * s;
00287 
00288 #   ifdef DEBUG
00289         if (tsig -> kind != TYPESIGNATURE) {
00290             dbgmsg("tsig_length: bad type signature\n");
00291             abort();
00292         }
00293 #   endif
00294     /* count number of constants */
00295         p = first(tsig -> ts_clist);
00296 #       ifdef DEBUG
00297             if (p -> kind != DEFCHARSIGS) {
00298                 dbgmsg("tsig_length: abnormal type list\n");
00299             }
00300 #       endif
00301         base = &(p -> dcs_0);
00302         for (s = base; s < base + NVECTORS; s++) {
00303              result += bitcnt(*s);
00304         }
00305     /* add the number of other components */
00306         result += length(tsig -> ts_clist) - 1;
00307         return(result);
00308 }
00309 
00310 extern NODE * substerr;
00311 
00312 
00313 extern struct cn * dontsubst;
00314 
00315 /*
00316  * tsubst (p, type_definition, expression, substm1)
00317  *
00318  *  Substitute expression for the local type identifier corresponding
00319  * to type_definition inside p.  Type_definition is either a type signature
00320  * or construction.
00321  * If substm1 is true then any id node
00322  * with a string table index of -1 refers to the local type id.
00323  *  We do not substitute inside a PROPER subexpression of p which is a copy
00324  * of type_definition.
00325  */
00326 
00327 NODE * tsubst1();
00328 
00329 int tsubst_count;   /* The number of tsubst1 calls started since the */
00330                     /* last tsubst call.  Used to handle top level   */
00331                     /* call slightly differently.                    */
00332 
00333 NODE * tsubst(p,tsig,expr,substm1)
00334 NODE * p, *tsig, *expr;
00335 boolean substm1;
00336 {
00337     NODE * result;
00338 
00339     clr_dlist;
00340     tsubst_count = 0;
00341     result = tsubst1(p, tsig, expr, substm1);
00342 #   ifdef TRACE
00343         if (result != p) {
00344             unparse_file = stdout;
00345             printf("tsubst: replaced\n");
00346             unparse(p);
00347             printf("\nwith 0x%X\n", result);
00348             unparse(result);
00349             printf("\n");
00350         } else {
00351             unparse_file = stdout;
00352             printf("tsubst: no place to substitute ");
00353             unparse(expr);
00354             printf(" into ");
00355             unparse(p);
00356             printf("\n");
00357         }
00358 #   endif
00359     return(result);
00360 }
00361 
00362 NODE * tsubst1(p,tsig,expr,substm1)
00363 NODE * p, *tsig, *expr;
00364 boolean substm1;
00365 {
00366     boolean mod_flag = FALSE; /* One of the descendants was modified */
00367     register int knd;         /* kind field of node being examined   */
00368     int plinkv;               /* bit vector indicating primary links */
00369                               /* to be followed to recursively       */
00370                               /* substitute in subtrees              */
00371     int sigv;                 /* bit vector indicating sig links     */
00372     register NODE ** q;       /* pointer to link field to be         */
00373                               /* recursively examined.               */
00374     NODE ** s;                /* temporary copy of list.             */
00375     NODE * tmpcopy[MAXFIELDS];/* temporary version of result         */
00376     NODE *v, *w;              /* temporaries                         */
00377     register int i;
00378     register struct cn * c;
00379     int j;
00380     int lim;
00381 
00382     if (p == ERR_SIG || p == NIL) return(p);
00383 
00384     tsubst_count++;
00385 
00386     switch ( knd = (p -> kind) ) {
00387         case LISTHEADER:
00388             i = 0;
00389             j = length(p);
00390             /* get sufficiently large chunk of memory to temporarily copy */
00391             /* the list minimizing number of allocations.                 */
00392                 if (j <= MAXFIELDS) {
00393                     s = tmpcopy;
00394                 } else {
00395                     s = (NODE **) malloc(j * sizeof(NODE *));
00396                 }
00397             maplist(q, p, {
00398                 s[i] = tsubst1(q, tsig, expr, substm1);
00399                         /* should be locked but ... */
00400                 if(s[i] != q) {
00401                     mod_flag = TRUE;
00402                 }
00403                 i++;
00404             });
00405             if (mod_flag) {
00406               /* convert the temporary copy in s to a real list structure */
00407               /* and return it */
00408                 NODE * result;
00409                 result = emptylist();
00410                 for (i = 0; i < j; i++) {
00411                     addright(result,s[i]);
00412                 }
00413                 if (j > MAXFIELDS) free(s);
00414                 return(result);
00415             } else {
00416                 return(p);
00417             }
00418         case MODPRIMARY:
00419             if (p -> pre_num == tsig -> pre_num) {
00420                 /* Nested references refer to local definition */
00421 #               ifdef TRACE
00422                     printf("Truncating subst at MODPRIMARY\n");
00423 #               endif
00424                 return(p);
00425             }
00426             /* Need to copy now so that local type id references get changed */
00427             if (p -> mp_type_modifier == NIL) {
00428                 /* forgetting node.  Can and should be discarded */
00429                 return (tsubst1(p -> mp_primary, tsig, expr, substm1));
00430             }
00431             v = copynode(p);
00432             add_dlist(p, v);
00433             chgfld(&(v -> mp_primary),
00434                    tsubst1(p -> mp_primary, tsig, expr, substm1));
00435             chgfld(&(v -> mp_type_modifier),
00436                    tsubst1(p -> mp_type_modifier, tsig, expr, substm1));
00437             if (p -> mp_primary == v -> mp_primary &&
00438                 p -> mp_type_modifier == v -> mp_type_modifier) {
00439                 return(v);
00440             } else if (p -> signature != ERR_SIG) {
00441                 chgfld(&(v -> signature), NIL);
00442                 v -> sig_done = SIG_UNKNOWN;
00443             }
00444             return(v);
00445 
00446         case RECORDCONSTRUCTION:
00447             if (p -> pre_num == tsig -> pre_num) {
00448                 /* Nested references refer to local definition */
00449 #               ifdef TRACE
00450                     printf("Truncating subst at RECORDCONSTRUCTION\n");
00451 #               endif
00452                 return(p);
00453             }
00454             /* Need to copy now so that local type id references get changed */
00455             v = copynode(p);
00456             add_dlist(p, v);
00457             chgfld(&(v -> rec_component_list),
00458                    tsubst1(p -> rec_component_list, tsig, expr, substm1));
00459             if (p -> signature != ERR_SIG) {
00460                 chgfld(&(v -> signature), NIL);
00461                 v -> sig_done = SIG_UNKNOWN;
00462             }
00463             return(v);
00464 
00465         case UNIONCONSTRUCTION:
00466             if (p -> pre_num == tsig -> pre_num) {
00467                 /* Nested references refer to local definition */
00468 #               ifdef TRACE
00469                     printf("Truncating subst at UNIONCONSTRUCTION\n");
00470 #               endif
00471                 return(p);
00472             }
00473             /* Need to copy now so that local type id references get changed */
00474             v = copynode(p);
00475             add_dlist(p, v);
00476             chgfld(&(v -> prod_components),
00477                    tsubst1(p -> prod_components, tsig, expr, substm1));
00478             if (p -> signature != ERR_SIG) {
00479                 chgfld(&(v -> signature), NIL);
00480                 v -> sig_done = SIG_UNKNOWN;
00481             }
00482             return(v);
00483 
00484         case PRODCONSTRUCTION:
00485           if (p -> pre_num == tsig -> pre_num) {
00486               /* Nested references refer to local definition */
00487 #             ifdef TRACE
00488                   printf("Truncating subst at PRODCONSTRUCTION\n");
00489 #             endif
00490               return(p);
00491           }
00492           /* treat parameter nodes as declarations, as for FUNCCONSTR below */
00493           {
00494             NODE * new_prod = copynode(p);
00495             NODE * new_params = emptylist();
00496 
00497             /* Build new list of parameters and add them to decl map */
00498               maplist(s, p -> prod_components, {
00499                 v = copynode(s);
00500                 add_dlist(s, v);
00501                 addright(new_params, v);
00502               });
00503             /* Substitute into parameter signatures */
00504               maplist(s, new_params, {
00505                 chgfld(&(s -> par_signature),
00506                        tsubst1(s -> par_signature, tsig, expr, FALSE));
00507               });
00508             /* replace components and clear signature */
00509               chgfld(&(new_prod -> prod_components), new_params);
00510               if (new_prod -> signature != ERR_SIG) {
00511                 chgfld(&(new_prod -> signature), NIL);
00512                 new_prod -> sig_done = SIG_UNKNOWN;
00513               }
00514             return(new_prod); 
00515           }
00516 
00517         /* The following constructs are treated specially to avoid */
00518         /* trying to substitute for declaring instances of ids     */
00519         /* Declarations are added to the list by the enclosing     */
00520         /* constructs.                                             */
00521         case TSCOMPONENT:
00522             v = tsubst1(p -> tsc_signature, tsig, expr, substm1);
00523             if (v != p -> tsc_signature) {
00524                 w = copynode(p);
00525                 chgfld(&(w -> tsc_signature), v);
00526                 return(w);
00527             } else {
00528                 return(p);
00529             }
00530 
00531         case WITHLIST:
00532             /* Don't try to substitute for local id */
00533             v = tsubst1(p -> wl_component_list, tsig, expr, substm1);
00534             if (v != p -> wl_component_list) {
00535                 w = copynode(p);
00536                 chgfld(&(w -> wl_component_list), v);
00537                 return(w);
00538             } else {
00539                 return(p);
00540             }
00541 
00542         case EXPORTLIST:
00543         case HIDELIST:
00544             if (p -> pre_num == tsig -> pre_num) {
00545                 /* Nested references refer to local definition */
00546 #               ifdef TRACE
00547                     printf("Truncating subst at export or hide list\n");
00548 #               endif
00549                 return(p);
00550             }
00551             v = tsubst1(p -> el_export_element_list, tsig, expr, substm1);
00552             if (v != p -> el_export_element_list) {
00553                 w = copynode(p);
00554                 chgfld(&(w -> el_export_element_list), v);
00555                 return(w);
00556             } else {
00557                 return(p);
00558             }
00559 
00560         case RECORDELEMENT:
00561             v = tsubst1(p -> re_denotation, tsig, expr, substm1);
00562             if (v != p -> re_denotation) {
00563                 w = copynode(p);
00564                 chgfld(&(w -> re_denotation), v);
00565                 return(w);
00566             } else {
00567                 return(p);
00568             }
00569 
00570         case PARAMETER:
00571             v = tsubst1(p -> par_signature, tsig, expr, substm1);
00572             if (v != p -> par_signature) {
00573                 w = copynode(p);
00574                 chgfld(&(w -> par_signature), v);
00575                 return(w);
00576             } else {
00577                 return(p);
00578             }
00579 
00580         case DECLARATION:
00581           { NODE * new_sig, * new_den;
00582 
00583             new_sig = tsubst1(p -> decl_signature, tsig, expr, substm1);
00584             new_den = tsubst1(p -> decl_denotation, tsig, expr, substm1);
00585             if (new_sig != p -> decl_signature
00586                 || new_den != p -> decl_denotation) {
00587                 w = copynode(p);
00588                 chgfld(&(w -> decl_signature), new_sig);
00589                 chgfld(&(w -> decl_denotation), new_den);
00590                 return(w);
00591             } else {
00592                 return(p);
00593             }
00594           }
00595 
00596         /* In the following two cases it is necessary to first      */
00597         /* add all declared identifiers to the list of declarations */
00598         /* This code will probably be executed at most once a       */
00599         /* century.  Therefore no attempt is made to avoid          */
00600         /* unnecessary copies.                                      */
00601         case BLOCKDENOTATION:
00602           {
00603             NODE * new_block = copynode(p);
00604             NODE * new_decls = emptylist();
00605 
00606             /* Build new list of declarations and add them to map */
00607               maplist(s, p -> bld_declaration_list, {
00608                 v = copynode(s);
00609                 add_dlist(s, v);
00610                 addright(new_decls, v);
00611               });
00612             /* Substitute into declarations */
00613               maplist(s, new_decls, {
00614                 chgfld(&(s -> decl_signature),
00615                        tsubst1(s -> decl_signature, tsig, expr, substm1));
00616                 chgfld(&(s -> decl_denotation),
00617                        tsubst1(s -> decl_denotation, tsig, expr, substm1));
00618               });
00619             /* substitute into body and replace declaration list */
00620               chgfld(&(new_block -> bld_den_seq),
00621                      tsubst1(p -> bld_den_seq, tsig, expr, substm1));
00622               chgfld(&(new_block -> bld_declaration_list), new_decls);
00623             /* Clear signature */
00624               if (new_block -> signature != ERR_SIG) {
00625                 chgfld(&(new_block -> signature), NIL);
00626                 new_block -> sig_done = SIG_UNKNOWN;
00627               }
00628             return(new_block); 
00629           }
00630 
00631         case FUNCCONSTR:
00632           {
00633             NODE * new_func = copynode(p);
00634             NODE * new_sig = copynode(p -> signature);
00635             NODE * new_params = emptylist();
00636 
00637             /* Build new list of parameters and add them to decl map */
00638               maplist(s, p -> signature -> fsig_param_list, {
00639                 v = copynode(s);
00640                 add_dlist(s, v);
00641                 addright(new_params, v);
00642               });
00643             /* Substitute into parameter signatures */
00644               maplist(s, new_params, {
00645                 chgfld(&(s -> par_signature),
00646                        tsubst1(s -> par_signature, tsig, expr, substm1));
00647               });
00648             /* substitute into body, result sig, and replace signature */
00649               if (new_sig -> fsig_result_sig != ERR_SIG) {
00650                 chgfld(&(new_sig -> fsig_result_sig),
00651                     tsubst1(new_sig -> fsig_result_sig, tsig, expr, substm1));
00652               }
00653               chgfld(&(new_sig -> fsig_param_list), new_params);
00654               chgfld(&(new_func -> fc_body),
00655                      tsubst1(p -> fc_body, tsig, expr, substm1));
00656               chgfld(&(new_func -> signature), new_sig);
00657             return(new_func); 
00658           }
00659 
00660         case FUNCSIGNATURE:
00661           {
00662             NODE * new_sig = copynode(p);
00663             NODE * new_params = emptylist();
00664 
00665             /* Build new list of parameters and add them to decl map */
00666               maplist(s, p -> fsig_param_list, {
00667                 v = copynode(s);
00668                 add_dlist(s, v);
00669                 addright(new_params, v);
00670               });
00671             /* Substitute into parameter signatures */
00672               maplist(s, new_params, {
00673                 chgfld(&(s -> par_signature),
00674                        tsubst1(s -> par_signature, tsig, expr, substm1));
00675               });
00676             /* substitute into result sig and change parameter list */
00677               if (new_sig -> fsig_result_sig != ERR_SIG) {
00678                 chgfld(&(new_sig -> fsig_result_sig),
00679                     tsubst1(new_sig -> fsig_result_sig, tsig, expr, substm1));
00680               }
00681               chgfld(&(new_sig -> fsig_param_list), new_params);
00682             return(new_sig); 
00683           }
00684 
00685         case TYPESIGNATURE:
00686             if (tsubst_count > 1) {
00687               if (p == tsig) {
00688                 /* Nested references refer to local definition */
00689 #               ifdef TRACE
00690                     printf("Truncating subst at TYPESIGNATURE\n");
00691 #               endif
00692                 return(p);
00693               }
00694               substm1 = FALSE; /* -1 no longer refers to the right type sig */
00695             }
00696             /* Need to copy now so that local type id references get changed */
00697             v = copynode(p);
00698             add_dlist(p, v);
00699             chgfld(&(v -> ts_clist),
00700                    tsubst1(p -> ts_clist, tsig, expr, substm1));
00701             return(v);
00702 
00703         case OPRID:
00704         case LETTERID:
00705 #           ifdef DEBUG
00706                 if(!p -> id_def_found && p -> id_str_table_index != -1
00707                    && yynerrs == 0) {
00708                     dbgmsg("tsubst: unresolved identifier reference:%s\n",
00709                            getname(p -> id_str_table_index));
00710                     abort();
00711                 }
00712 #           endif
00713             if(!p -> id_def_found && p -> id_str_table_index != -1) {
00714                 /* undeclared identifier */
00715                 return(p);
00716             }
00717             if (p -> id_last_definition != NIL
00718                 && p -> id_last_definition -> kind == DECLARATION
00719                 && p -> id_last_definition -> decl_sig_transp) {
00720                 NODE * tmp = tsubst1(p -> id_last_definition -> decl_denotation,
00721                                      tsig, expr, substm1);                    
00722                 if (tmp != p -> id_last_definition -> decl_denotation) {    
00723                     return(tmp);                                           
00724                 }                                                          
00725                 /* else treat it like any other identifier, so we don't */ 
00726                 /* make extra copies.                                   */
00727             }
00728             if(   p -> sel_type == NIL && p -> id_str_table_index != -1
00729                   && is_declared_by(p,tsig)
00730                || (substm1 && p -> id_str_table_index == -1)) {
00731                 /* substitute the expression */
00732                     /* check whether substitution is safe */
00733                         c = dontsubst;
00734                         while(c != NIL) {
00735                             if( is_descendant((NODE *)(cn_head(c)), expr) ) {
00736                                 substerr = (NODE *)cn_head(c);
00737                             }
00738                             c = cn_tail(c);
00739                         }
00740                     return(expr);
00741             }
00742             if (p -> sel_type == NIL && p -> id_str_table_index != -1
00743                 && dl_new_decl(p) != p -> id_last_definition) {
00744                 /* declaration changed - need to copy node */
00745                 NODE * q = copynode(p);
00746                 q -> id_last_definition = dl_new_decl(p);
00747                 if (q -> signature != ERR_SIG) {
00748                     q -> sig_done = SIG_UNKNOWN;
00749                     chgfld(&(q -> signature), NIL);
00750                 }
00751                 q -> id_appl = NIL;
00752                 return(q);
00753             }
00754             if (p -> sel_type == NIL) {
00755                 /* id_appl may be wrong, but inside a signature it's */
00756                 /* not used.                                         */
00757                 return(p);
00758             } else {
00759                 NODE * new_sel_type = tsubst1(p -> sel_type, tsig,
00760                                               expr, substm1);
00761 
00762                 if (new_sel_type == p -> sel_type) {
00763                     /* id_appl may be wrong, but inside a signature it's */
00764                     /* not used.                                         */
00765                     return(p);
00766                 } else {
00767                     NODE * q = copynode(p);
00768                     if (q -> signature != ERR_SIG) {
00769                         q -> sig_done = SIG_UNKNOWN;
00770                         chgfld(&(q -> signature), NIL);
00771                     }
00772                     chgfld(&(q -> sel_type), new_sel_type);
00773                     q -> id_appl = NIL;
00774                     return(q);
00775                 }
00776             }
00777 
00778         /* else do the copy: */
00779     }
00780     i = 0;
00781     q = (NODE **) p;
00782     plinkv = stplinks[knd];
00783     sigv = stsigs[knd];
00784     lim = stsize[knd];
00785     for(; i < lim; (plinkv <<= 1, sigv <<= 1, q++, i++)) {
00786         if (plinkv < 0 && sigv >= 0 /* non-sig primary link */) {
00787             tmpcopy[i] = tsubst1(*q, tsig, expr, substm1);
00788                     /* should be locked but ... */
00789             if(tmpcopy[i] != *q) {
00790                 mod_flag = TRUE;
00791             }
00792         } else {
00793             tmpcopy[i] = *q;
00794                     /* again ... */
00795         }
00796     }
00797     if (mod_flag) {
00798         /* clear signature and sig_done fields */
00799             for((sigv = stsigs[knd], i = 0); sigv != 0;
00800                 (sigv <<= 1, i++)) {
00801                 if (sigv < 0) {
00802                     tmpcopy[i] = NIL;
00803                     tmpcopy[i+1] = SIG_UNKNOWN;
00804                 }
00805             }
00806         return(copynode(tmpcopy));
00807     } else {
00808         return(p);
00809     }
00810 }
00811 
00812 
00813 /*
00814  *  inscomp(type_signature, id_node, component_signature, enclosing_type)
00815  * 
00816  *  Insert a component with name given by id_node and the given signature
00817  * into the given type signature.  This is done in place, i.e. it
00818  * CLOBBERS THE ORIGINAL TYPE SIGNATURE.  (The dcs_exceptions list
00819  * is copied if it needs to be updated.)
00820  *  The appropriate substitutions of local type identifiers are made.
00821  *
00822  *  Sets comp_index to the position of the inserted component.
00823  */
00824 
00825 
00826 void
00827 inscomp(sig,id,csig,ctype)
00828 NODE * sig, * id;
00829 NODE * csig;
00830 {
00831     register NODE * dcs;  /* DEFCHARSIGS component */
00832     register boolean is_char;
00833                             /* ind refers to a single character quoted id */
00834     char * name;            /* identifier name */
00835     char character;         /* identifier name (non-quote char) when      */
00836                             /* is_char is true.                           */
00837     unsigned ind = id -> id_str_table_index;
00838     int i;
00839     NODE * ntid;            /* new local type identifier node to substitute */
00840                             /* in csig                                      */
00841 
00842     if (sig == ERR_SIG) return;
00843 #   ifdef DEBUG
00844         if (sig -> kind != TYPESIGNATURE) {
00845             dbgmsg("inscomp: bad type signature\n");
00846             abort();
00847         }
00848 #   endif
00849 
00850     dcs = first(sig -> ts_clist);
00851 #   ifdef DEBUG
00852         if (dcs -> kind != DEFCHARSIGS) {
00853             dbgmsg("inscomp: abnormal type list\n");
00854         }
00855 #   endif
00856     comp_index = 0;
00857     name = getname(ind);
00858     if(is_char = (name[0] == '\'' && name[2] == '\'' && is_const(csig,ctype))) {
00859         character = name[1];
00860         /* invalidate inline info for constants */
00861           sig -> ts_const_code = sig -> ts_string_code
00862                                = sig -> ts_element_code = NIL;
00863         {
00864             unsigned * word;
00865             int bitno;
00866             int wordno;
00867             unsigned * base = &(dcs -> dcs_0);
00868             unsigned * s;
00869 
00870             wordno = ((int) character) / WORDLENGTH;
00871             word = base + wordno;
00872             bitno = ((int) character) - wordno * WORDLENGTH;
00873             /* update comp_index */
00874                 for (s = base; s < base + wordno; s++){
00875                     comp_index += bitcnt(*s);
00876                 }
00877                 for (i = 0; i < bitno; i++) {
00878                     if ((((int) *word) << i) < 0) 
00879                         comp_index++;
00880                 }
00881             /* set appropriate bit */
00882                 *word |= 1 << (WORDLENGTH-1 - bitno);
00883         }
00884         /* Add it to exception list, if appropriate */
00885         if (special_tp(csig -> fsig_special) != NOT_SPECIAL
00886             || csig -> fsig_inline_code != NIL
00887             || csig -> fsig_construction != NIL) {
00888             if (dcs -> dcs_exceptions == NIL) {
00889                 initfld(&(dcs -> dcs_exceptions), emptylist());
00890             } else {
00891                 chgfld(&(dcs -> dcs_exceptions),
00892                        copylist(dcs -> dcs_exceptions));
00893             }
00894             add_dcse(dcs -> dcs_exceptions, character,
00895                      csig -> fsig_inline_code,
00896                      csig -> fsig_special, csig -> fsig_construction);
00897         }
00898     } else {
00899         unsigned * base = &(dcs -> dcs_0);
00900         unsigned * s;
00901         NODE * new_tsc;
00902 
00903         /* build new local type id to substitute in */
00904             ntid = mknode(LETTERID, 0);
00905             ntid -> id_last_definition = sig;
00906             ntid -> id_def_found = TRUE;
00907 
00908         /* build new signature component */
00909             new_tsc = mknode(TSCOMPONENT, id, NIL);
00910             if (csig != ERR_SIG) {
00911                if (ctype == NIL) {
00912                    initfld(&(new_tsc -> tsc_signature),
00913                            csig);
00914                } else {
00915                    initfld(&(new_tsc -> tsc_signature),
00916                            tsubst(csig, ctype, ntid, TRUE));
00917                }
00918             } else {
00919                 new_tsc -> tsc_signature = ERR_SIG;
00920             }
00921 
00922         mapinslist(p, sig -> ts_clist, {
00923             if (p == NIL) { 
00924                 INSERT(new_tsc);
00925                 return;
00926             }
00927             switch (p -> kind) {
00928               case TSCOMPONENT:
00929                 if ((i = strcmp(name, 
00930                                 getname(p->tsc_id->id_str_table_index))) < 0
00931                     || i == 0 && comp_st(csig,p->tsc_signature,ctype,sig) < 0) {
00932                     INSERT(new_tsc);
00933                     return;
00934                 } else {
00935                     comp_index++;
00936                 }
00937                 break;
00938               case DEFCHARSIGS:
00939                 /* count number of constants */
00940                     for (s = base; s < base + NVECTORS; s++) {
00941                         comp_index += bitcnt(*s);
00942                     }
00943                 break;
00944               IFDEBUG(
00945                 default:
00946                     dbgmsg("getcomp: bad tsc\n");
00947               )
00948             }
00949         });
00950     }
00951 }
00952 
00953 
00954 /*
00955  *  delcomp(type_signature, deletion_vector)
00956  *
00957  *  Return a copy of type_signature with the components indicated by the
00958  * deletion vector (a bit vector given as a sequence of ints) deleted from
00959  * the type signature.
00960  *  Set changed_strings if either a constant or concatenation
00961  * is replaced.  Reset it otherwise.
00962  */
00963 
00964 boolean changed_strings;
00965 
00966 NODE *
00967 delcomp(sig, delv)
00968 NODE * sig;
00969 int * delv;
00970 {
00971     NODE * p;
00972     int delword, delbit;    /* current word and bit in deletion vector */
00973 #   define INCPOS if (++delbit >= WORDLENGTH) { delword++; delbit = 0; }
00974 #   define BITSET ((delv[delword] << delbit) < 0)
00975 
00976     changed_strings = FALSE;
00977     if (sig == ERR_SIG) return;
00978 #   ifdef DEBUG
00979         if (sig -> kind != TYPESIGNATURE) {
00980             dbgmsg("delcomp: bad type signature\n");
00981             abort();
00982         }
00983 #   endif
00984     /* Make a new copy of the signature */
00985         sig = copynode(sig);
00986         {   NODE * clist = emptylist();
00987             maplist(s, sig -> ts_clist, {
00988                 if (s -> kind == DEFCHARSIGS) {
00989                     addright(clist, copynode(s));
00990                 } else {
00991                     addright(clist, s);
00992                 }
00993             });
00994             chgfld(&(sig->ts_clist), clist);
00995         }
00996     if (sig == ERR_SIG) return;
00997 #   ifdef DEBUG
00998         if (sig -> kind != TYPESIGNATURE) {
00999             dbgmsg("delcomp: bad type signature\n");
01000             abort();
01001         }
01002 #   endif
01003 
01004     delword = delbit = 0;
01005     /* clear appropriate bits in DEFCHARSIGS node */
01006         p = first(sig -> ts_clist);
01007 #       ifdef DEBUG
01008             if (p -> kind != DEFCHARSIGS) {
01009                 dbgmsg("delcomp: abnormal type list\n");
01010             }
01011 #       endif
01012         {
01013             unsigned * word;
01014             int bitno;
01015             int wordno;
01016             unsigned * base = &(p -> dcs_0);
01017             long s;
01018 
01019             for (wordno = 0; wordno < NVECTORS; wordno++) {
01020                 word = base + wordno;
01021                 for (bitno = 0; bitno < WORDLENGTH; bitno ++) {
01022                     s = (long)(*word << bitno);
01023                     if (s == 0) break; /* only an optimization */
01024                     if (s < 0 /* component present in signature */) {
01025                         if (BITSET) {
01026                             /* delete this component */
01027                                 *word &= ~(1 << (WORDLENGTH-1 - bitno));
01028                             changed_strings = TRUE;
01029                         }
01030                         /* move to next component in deletion vector */
01031                         INCPOS;
01032                     }
01033                 }
01034             }
01035         }
01036     /* delete components from rest of signature */
01037         mapinslist(p, sig -> ts_clist, {
01038             if (p == NIL) { 
01039                 break;
01040             }
01041             if (p -> kind == TSCOMPONENT) {
01042                 if (BITSET) {
01043                     extern long indx_pconc;
01044                     extern long indx_sconc;
01045 
01046                     /* delete this component */
01047                         DELETE;
01048                     if (p -> tsc_id -> id_str_table_index == indx_pconc
01049                         || p -> tsc_id -> id_str_table_index == indx_sconc) {
01050                         changed_strings = TRUE;
01051                     }
01052                 }
01053                 /* move to next component in deletion vector */
01054                     INCPOS;
01055             }
01056             IFDEBUG(
01057                 if(p -> kind != TSCOMPONENT && p -> kind != DEFCHARSIGS) {
01058                     dbgmsg("getcomp: bad tsc\n");
01059                 }
01060             )
01061         });
01062     return(sig);
01063 }
01064 
01065 
01066 /* Returns true if type signature sig contains at most one component with */
01067 /* name corresponding to string table index ind.                          */
01068 boolean
01069 is_unique(sig,ind)
01070 NODE * sig;
01071 int ind;
01072 {
01073     register NODE * p;
01074     register boolean is_char;
01075                             /* ind refers to a single character quoted id */
01076     char * name;            /* identifier name */
01077     char character;         /* identifier name (non-quote char) when      */
01078                             /* is_char is true.                           */
01079     int nfound = 0;         /* number of components with this name found  */
01080                             /* so far.                                    */
01081 
01082     if (sig == ERR_SIG) return(TRUE);
01083 #   ifdef DEBUG
01084 #     ifdef VAX
01085         if (nargs() != 2) {
01086             dbgmsg("is_unique: wrong number of args\n");
01087             abort();
01088         }
01089 #     endif
01090         if (sig -> kind != TYPESIGNATURE) {
01091             dbgmsg("is_unique: bad type signature\n");
01092             abort();
01093         }
01094 #   endif
01095 
01096     name = getname(ind);
01097     if(is_char = (name[0] == '\'' && name[2] == '\'')) character = name[1];
01098     maplist(p, sig -> ts_clist, {
01099         if (p -> kind == TSCOMPONENT) {
01100             if (p -> tsc_id -> id_str_table_index == ind) {
01101                 nfound++;
01102             }
01103         }
01104         /* Check whether it is a character with a default signature */
01105             if(p -> kind == DEFCHARSIGS) {
01106 
01107                 unsigned word;
01108                 int bitno;
01109                 int wordno;
01110                 unsigned * base = &(p -> dcs_0);
01111                 unsigned * s;
01112 
01113                 if (is_char) {
01114                     wordno = ((int) character) / WORDLENGTH;
01115                     word = *(base + wordno);
01116                     bitno = ((int) character) - wordno * WORDLENGTH;
01117                 }
01118 
01119                 if ( is_char && (((int) word) << bitno) < 0 ) {
01120                     /* type component appears in this node */
01121                     nfound++;
01122                 }
01123             }
01124         IFDEBUG(
01125             if(p -> kind != TSCOMPONENT && p -> kind != DEFCHARSIGS) {
01126                 dbgmsg("getcomp: bad tsc\n");
01127             }
01128         )
01129     });
01130     return(nfound <= 1);
01131 }

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