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

Go to the documentation of this file.
00001 /* Perform findsigs task in the case of applications.  We insure that the */
00002 /* final operator signature is not an ID node.                            */
00003 # define TRACE
00004 # undef TRACE
00005 # define DEBUG
00006 
00007 # define TRACE2
00008 # undef TRACE2
00009 # include <stdio.h>
00010 # include "parm.h"
00011 # include "arith.h"
00012 
00013 # ifdef TRACE
00014 #   define IFTRACE(x) x
00015 # else
00016 #   define IFTRACE(x)
00017 # endif
00018 
00019 # ifdef DEBUG
00020 #   define IFDEBUG(x) x
00021 # else
00022 #   define IFDEBUG(x)
00023 # endif
00024 
00025 # include "stree/ststructs.mh"
00026 # ifdef DEBUG
00027 #   include "stree/is_ptr.h"
00028 # endif
00029 
00030 # include "sigs.h"
00031 
00032 # include "stree/Array.h"
00033 
00034 /* Needed to construct type signatures for constructions */
00035 # include "pass1/stt/sttdefs.h"
00036 
00037 extern FILE * unparse_file;
00038 
00039 extern boolean Gflag;
00040 
00041 extern int yynerrs;
00042 
00043 # define ERR_NODE_DEFINED
00044 extern NODE * err_node;        /* node to be used for error message in lieu */
00045                    /* of current node.  Used by errmsg macros   */
00046 extern char * err_msg;         /* message to be used in lieu of usual one   */
00047 
00048 NODE * declerr;     /* declsig failure indication */
00049 
00050 NODE * substerr;    /* subst error indication           */
00051         /* Set to something other than SUCCESS if       */
00052         /* subst is asked to substitute an incompletely */
00053         /* expanded expression, as indicated by         */
00054         /* dontsubst                                    */
00055 
00056 extern int match_len;      /* length of argument type.  Set by amatch. */
00057 extern unsigned * match_delv;  /* bitvector indicating necessary deletions */
00058                    /* set by amatch.                           */
00059 
00060 # ifdef VAX
00061     int nargs();
00062 # endif
00063 
00064 void find_inline();
00065 
00066 void Gfind_inline();
00067 
00068 NODE * coerce();
00069 
00070 NODE * infer_args();
00071 
00072 NODE * declsig();
00073 
00074 NODE * fixhints();
00075 
00076 char * (* spcl_to_inline)();
00077 
00078 boolean may_fail; /* current signature deduction may fail */
00079                   /* without dire consequences.           */
00080 
00081 NODE * findapplsig(p)
00082 register NODE * p;
00083 {
00084         NODE * args = p -> ap_args;
00085         NODE * op = p -> ap_operator;
00086         NODE * r;
00087         NODE * q;
00088 
00089 #       ifdef TRACE
00090             unparse_file = stdout;
00091             printf("Finding signature of application:");
00092             unparse(p);
00093             printf("\n");
00094 #       endif
00095         /* find signatures of the arguments */
00096             maplist(q, args, {
00097                 if ((r = findsig(q,FALSE)) != SUCCESS) {
00098                     p -> sig_done = SIG_UNKNOWN;
00099                     return(r);
00100                 }
00101                 if (q -> signature == ERR_SIG) {
00102                     p -> signature = ERR_SIG;
00103                     p -> sig_done = SIG_DONE;
00104                     return(SUCCESS);
00105                 }
00106             });
00107        /* find signature of the operator */
00108             if (op -> kind == OPRID || op -> kind == LETTERID) {
00109                 /* use argument list to find right decl. */
00110                     op -> id_appl = p;
00111             }
00112             if ((r = findsig(op,FALSE)) != SUCCESS) {
00113                 p -> sig_done = SIG_UNKNOWN;
00114                 return(r);
00115             }
00116             if (op -> signature == ERR_SIG) {
00117                 p -> signature = ERR_SIG;
00118                 p -> sig_done = SIG_DONE;
00119                 return(SUCCESS);
00120             }
00121             /* Make sure operator signature is not an identifier. */
00122                 while (op -> signature -> kind == OPRID
00123                        || op -> signature -> kind == LETTERID) {
00124                     NODE * decl = op -> signature -> id_last_definition;
00125 
00126                     if (decl -> kind == DECLARATION
00127                         && decl -> decl_sig_transp) {
00128                         NODE * den = decl -> decl_denotation;
00129 
00130                         if (den -> kind == LETTERID
00131                             || den -> kind == OPRID
00132                             || den -> kind == FUNCSIGNATURE) {
00133                             chgsig(op, den);
00134                         } else {
00135                             break;
00136                         }
00137 #                   ifdef DEBUG
00138                       } else {
00139                           dbgmsg("Findapplsig: bad op sig\n");
00140                           abort(op, decl);
00141 #                   endif
00142                     }
00143                 }
00144             if (op -> signature -> kind != FUNCSIGNATURE) {
00145                 errmsg0(
00146                     op,
00147                     "Error - non-function used as operator"
00148                 );
00149                 p -> signature = ERR_SIG;
00150                 p -> sig_done = SIG_DONE;
00151                 return(SUCCESS);  /* i.e. this routine already */
00152                                   /* dealt with the error.     */
00153             }
00154         /* insert Valueof and constant applications, */
00155         /* omitted arguments,
00156         /* and type coercions (forgetting)           */
00157           {
00158             NODE * op_sig = op -> signature;
00159             NODE * ext_args;
00160 
00161             if (length(op_sig -> fsig_param_list) >= length(args)) {
00162                 NODE * par_sig;
00163                 NODE * nargs = emptylist();  /* modifed version  */
00164                                              /* of argument list */
00165 
00166                 begin_map2lists (s, args,
00167                                  r, op_sig -> fsig_param_list) {
00168                     par_sig = r -> par_signature;
00169                     while (par_sig -> kind == LETTERID
00170                            || par_sig -> kind == OPRID) {
00171                         par_sig = par_sig -> id_last_definition
00172                                           -> decl_denotation;
00173 #                       ifdef TRACE
00174                           unparse_file = stdout;
00175                           printf("applsig: Changed parameter signature to ");
00176                           unparse(par_sig);
00177                           printf("\n");
00178 #                       endif
00179                     }
00180                     if (s -> signature != ERR_SIG &&
00181                         par_sig -> kind == VALSIGNATURE &&
00182                         s -> signature -> kind != VALSIGNATURE) {
00183                         NODE * narg = coerce(s);
00184 
00185                         if((q = findsig(narg,FALSE)) != SUCCESS) {
00186                             p -> signature = NIL;
00187                             vfree(nargs);
00188                             p -> sig_done = SIG_UNKNOWN;
00189                             return(q);
00190                         }
00191                         addright(nargs, narg);
00192                     } else {
00193                         addright(nargs, s);
00194                     }
00195                 } end_map2lists;
00196                 if (length(op_sig -> fsig_param_list)
00197                     > length(args)) {
00198                   /* Add any missing arguments */
00199                     ext_args = infer_args(nargs,
00200                                           op_sig -> fsig_param_list,
00201                                           p -> ap_void_decl, op);
00202                     if (ext_args == NIL) {
00203                         p -> signature = ERR_SIG;
00204                         p -> sig_done = SIG_DONE;
00205                         errmsg0(p, "Can't infer missing arguments");
00206                         return(SUCCESS);
00207                     } else {
00208 #                       ifdef TRACE
00209                           printf("Added args\n");
00210 #                       endif
00211                         nargs = ext_args;
00212                     }
00213                 }
00214                 args = nargs;
00215                 nargs = emptylist();
00216                 begin_map2lists (s, args,
00217                                  r, op_sig -> fsig_param_list) {
00218                   par_sig = r -> par_signature;
00219                   if (par_sig -> kind == LETTERID
00220                       || par_sig -> kind == OPRID) {
00221                     par_sig = sig_structure(par_sig);
00222                   }
00223                   if (par_sig -> kind == TYPESIGNATURE) {
00224                       NODE * s_par_sig;
00225 
00226                       substerr = SUCCESS;
00227                       s_par_sig = subst(par_sig,
00228                                         op_sig -> fsig_param_list,
00229                                         args);
00230                       lock(s_par_sig);
00231                       if (substerr == SUCCESS
00232                           && amatch(s -> signature, s_par_sig)
00233                           && match_delv != NIL) {
00234                           /* components need to be forgotten */
00235                           NODE * narg = mknode( MODPRIMARY,
00236                                                 s,
00237                                                 NIL,
00238                                                 match_delv
00239                                               );
00240 
00241                           IFTRACE(
00242                             printf("Adding forgetting node to:");
00243                             unparse_file = stdout;
00244                             unparse(s);
00245                             printf("\n");
00246                           )
00247                           narg -> mp_orig_length = match_len;
00248                           initfld(&(narg->signature),
00249                                   delcomp(s -> signature,
00250                                           match_delv));
00251                               /* s_par_sig would be OK, exc. */
00252                               /* for opt. info.              */
00253                           narg -> sig_done = SIG_DONE;
00254                           addright(nargs, narg);
00255                       } else {
00256                         if (substerr != SUCCESS) {
00257                           /* Cant  decide whether and how to do */
00258                           /* coercion yet.                      */
00259                           p -> sig_done = SIG_UNKNOWN;
00260                           return(substerr);
00261                         }
00262                         addright(nargs, s);
00263                       }
00264                       vfree(unlock(s_par_sig));
00265                   } else {
00266                       addright(nargs, s);
00267                   }
00268                 } end_map2lists;
00269                 chgfld(&(p -> ap_args), nargs);
00270                 args = nargs;
00271             }
00272           }
00273         /* compute result signature */
00274 #           ifdef DEBUG
00275                 if (op -> signature -> fsig_result_sig == NIL) {
00276                     dbgmsg("findsig:APPL: missing result sig\n");
00277                 }
00278 #           endif
00279             substerr = SUCCESS; /* reinitialize error indication */
00280             initsig(p,
00281                     subst(op -> signature -> fsig_result_sig,
00282                           op -> signature -> fsig_param_list,
00283                           args
00284                     )
00285             );
00286             /* Add special info for arrays */
00287               if (special_tp(op -> signature -> fsig_special)
00288                   == STD_ARRAY) {
00289                   fix_array_sig(p -> signature,
00290                                 first(args), second(args));
00291               }
00292             if (substerr != SUCCESS) {
00293               /* clear signature field */
00294                 chgsig(p, NIL);
00295                 p -> sig_done = SIG_UNKNOWN;
00296             } else {
00297                 p -> sig_done = SIG_DONE;
00298 #               ifdef DEBUG
00299                     if (p -> signature == NIL) {
00300                         dbgmsg("findsig produced bad APPL sig\n");
00301                     }
00302 #               endif
00303             }
00304             if (has_sig(p)
00305                 && (p -> signature -> kind == FUNCSIGNATURE
00306                     || p -> signature -> kind == TYPESIGNATURE)) {
00307                 /* leaving environment which might be needed */
00308                 /* to evaluate a function produced by this   */
00309                 /* application.                              */
00310                 clear_slink_known(p -> signature);
00311                     /* We should really copy the signature  */
00312                     /* rather than zapping it in place, but */
00313                     /* this is safe, and it rarely matters. */
00314             }
00315             return(substerr);
00316 }

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