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

Go to the documentation of this file.
00001 # include <stdio.h>
00002 # include "parm.h"
00003 # include "arith.h"
00004 
00005 # include "stree/ststructs.mh"
00006 
00007 # include "sigs.h"
00008 
00009 # include "pass3/decl_pairs.h"
00010 
00011 extern FILE * unparse_file;
00012 
00013 /* Knows about implementation of lists.  There doesn't seem to be a clean */
00014 /* and efficient way to merge two lists otherwise.                        */
00015 
00016 extern unsigned stplinks[];
00017 
00018 /*
00019  * amatch(arg_sig, par_sig)
00020  *
00021  *  Asymmetric match of argument signature against parameter
00022  * signature.  If both are type signatures, both forgetting
00023  * and reordering may be applied to par_sig.  (Reordering is
00024  * trivial since it is assumed that all type signatures
00025  * are in canonical form.)
00026  *  Note however
00027  * that it is assumed that par_sig has already been expanded by
00028  * substituting arguments for parameters.
00029  *  Returns TRUE or FALSE depending on whether the arguments match.
00030  *  Sets match_delv to point to a bit vector describing wich type
00031  * components need to be forgotten when a type argument is passed.
00032  * NIL indicates no forgetting is necessary.  If the argument signature
00033  * is a type signature match_len is set to the length of the type 
00034  * representation.
00035  *  If the match fails, but was "close", failed_asig and failed_psig are set.
00036  * If both signatures are type signatures,
00037  * failed_comp is set to the component of the signature responsible
00038  * for the failure.
00039  */
00040 
00041 unsigned * match_delv;
00042 int match_len;
00043 static int delv_len;
00044 
00045 NODE * failed_comp;
00046 NODE * failed_asig;
00047 NODE * failed_psig;
00048 
00049 /* Initialize delv to an appropriate block of memory    */
00050 /* if not done already.                                 */
00051 /* assumes that match_len has been properly initialized */
00052 #define init_delv() \
00053     if (match_delv == NIL) { \
00054         delv_len = roundup(match_len, WORDLENGTH) >> 3; \
00055         /* allocate deletion vector */ \
00056             match_delv = (unsigned *)malloc(delv_len); \
00057             delv_len >>= LOGWL - 3; /* Convert to words */\
00058             for (s = match_delv; \
00059                 s < match_delv + delv_len; s++) { \
00060                 *s = 0; \
00061             } \
00062     }
00063 
00064 amatch(asig,psig)
00065 NODE * asig,*psig;
00066 {
00067     int asig_ind = 0;   /* current component number in asig */
00068     int i, j, k;
00069     unsigned *s, *t;
00070 
00071     if (failed_asig != NIL) {
00072         vfree(unlock(failed_asig));
00073     }
00074     if (failed_psig != NIL) {
00075         vfree(unlock(failed_psig));
00076     }
00077     if (failed_comp != NIL) {
00078         vfree(unlock(failed_comp));
00079     }
00080     match_delv = NIL;
00081     failed_comp = failed_asig = failed_psig = NIL;
00082     if (asig == ERR_SIG || psig == ERR_SIG) return(TRUE);
00083     /* Replace identifier signatures by their bindings           */
00084     /* This is safe because we checked for circularity in sigids */
00085       if (asig -> kind == LETTERID || asig -> kind == OPRID) {
00086         asig = sig_structure(asig);
00087       }
00088       if (psig -> kind == LETTERID || psig -> kind == OPRID) {
00089         psig = sig_structure(psig);
00090 #       ifdef TRACE
00091           printf("Match: Replaced psig by (%X) ", psig);
00092           unparse_file = stdout;
00093           unparse(psig);
00094           printf("\n");
00095 #       endif
00096       }
00097     if (asig -> kind != psig -> kind) return(FALSE);
00098     if (asig -> kind != TYPESIGNATURE) {
00099         if (comp_st(asig, psig, NIL, NIL) != 0) {
00100             failed_asig = lock(asig);
00101             failed_psig = lock(psig);
00102             return(FALSE);
00103         } else {
00104             return(TRUE);
00105         }
00106     }
00107     /* Both are type signatures */
00108     {
00109         struct cn *acomps, *pcomps; /* pointers to lists of type components */
00110                                     /* remaining to be examined.            */
00111         NODE * acomp, * pcomp;      /* current type components              */
00112         unsigned * p, * q;
00113         int i;
00114 
00115         match_len = tsig_length(asig);
00116 
00117         acomps = asig -> ts_clist -> lh_first;
00118         pcomps = psig -> ts_clist -> lh_first;
00119 #       ifdef DEBUG
00120             if (acomps == NIL) {
00121                 dbgmsg("amatch: NIL type sig\n");
00122             }
00123 #       endif
00124         pcomp = (NODE *)cn_head(pcomps);
00125         while (acomps != NIL) {
00126             acomp = (NODE *)cn_head(acomps);
00127             switch(acomp -> kind) {
00128                 case DEFCHARSIGS:
00129 #                   ifdef DEBUG
00130                         if (pcomp -> kind != DEFCHARSIGS) {
00131                             dbgmsg("amatch: non normal form type sig\n");
00132                         }
00133 #                   endif
00134                     p = &(acomp -> dcs_0);
00135                     q = &(pcomp -> dcs_0);
00136                     for (i = 0; i < NVECTORS; i++) {
00137                         if (((*q) & ~(*p)) != 0) {
00138                             failed_asig = lock(asig);
00139                             failed_psig = lock(psig);
00140                             failed_comp = lock(pcomp);
00141                             return(FALSE);
00142                         } else if (((*p) & ~(*q)) != 0) {
00143                             /* forgetting required */
00144                             init_delv();
00145                             j = *p;
00146                             k = *q;
00147                             while (j != 0 /* argument components left */) {
00148                                 if (j < 0) {
00149                                     /* argument component in this position */
00150                                     if (k >= 0) {
00151                                       /* delete this component */
00152                                         t = match_delv
00153                                             + (asig_ind >> LOGWL);
00154                                         *t |=  1 << (WORDLENGTH-1 -
00155                                                      mod(asig_ind,WORDLENGTH));
00156                                     }
00157                                     asig_ind++;
00158                                 }
00159                                 j <<= 1; k <<= 1;
00160                             }
00161                         } else {
00162                             asig_ind += bitcnt(*p);
00163                         }
00164                         p++; q++;
00165                     }
00166                     pcomps = cn_tail(pcomps);
00167                     if (pcomps != NIL) {
00168                         pcomp = (NODE *)cn_head(pcomps);
00169                     }
00170                     break;
00171                 case TSCOMPONENT:
00172                     if ( pcomps == NIL ||
00173                          acomp -> tsc_id -> id_str_table_index !=
00174                          pcomp -> tsc_id -> id_str_table_index ||
00175                          ( acomp -> tsc_signature != ERR_SIG
00176                            && pcomp -> tsc_signature != ERR_SIG
00177                            && comp_st(acomp -> tsc_signature,
00178                                        pcomp -> tsc_signature,
00179                                        asig, psig, FALSE) != 0 )) {
00180                         /* no matching parameter component */
00181                         init_delv();
00182                         t = match_delv + (asig_ind >> LOGWL);
00183                         *t |= 1 << (WORDLENGTH-1 - mod(asig_ind,WORDLENGTH));
00184                     } else {
00185                         /* pcomp matches */
00186                         if (pcomps != NIL)
00187                             pcomps = cn_tail(pcomps);
00188                         if (pcomps != NIL) 
00189                             pcomp = (NODE *)cn_head(pcomps);
00190                     }
00191                     asig_ind++;
00192                     break;
00193 #           ifdef DEBUG
00194                 default:
00195                     dbgmsg("amatch: bad type signature component\n");
00196 #           endif
00197             }
00198             acomps = cn_tail(acomps);
00199         }
00200         if (pcomps != NIL) {
00201             failed_asig = lock(asig);
00202             failed_psig = lock(psig);
00203             failed_comp = lock(pcomp);
00204             return(FALSE);
00205         } else {
00206             return(TRUE);
00207         }
00208     }
00209 }
00210 
00211 

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