00001 # define DEBUG
00002
00003 # ifdef DEBUG
00004 # define IFDEBUG(x) x
00005 # else
00006 # define IFDEBUG(x)
00007 # endif
00008
00009 # define TRACE
00010 # undef TRACE
00011
00012 # include <stdio.h>
00013 # include "parm.h"
00014
00015 # include "stree/ststructs.mh"
00016
00017 # include "sigs.h"
00018
00019 extern int comp_index;
00020
00021 extern NODE * declerr;
00022
00023 extern boolean may_fail;
00024
00025 extern FILE * unparse_file;
00026
00027 NODE * finddecl1();
00028
00029 NODE * prev_def();
00030
00031 boolean def_match();
00032
00033 NODE * unshare();
00034
00035 NODE * subst();
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057 NODE *
00058 finddecl(id)
00059 NODE * id;
00060 {
00061 NODE * q;
00062
00063 if (id -> id_appl == NIL) {
00064 return(finddecl1(id, id -> id_appl, TRUE));
00065 } else {
00066
00067 q = finddecl1(id, id -> id_appl, TRUE);
00068 if (q != SUCCESS || id -> id_def_found)
00069 return(q);
00070
00071 return(finddecl1(id, id -> id_appl, FALSE));
00072 }
00073 }
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083 NODE *
00084 finddecl1(id, appl, exact)
00085 NODE * id, * appl;
00086 boolean exact;
00087 {
00088 NODE * usl;
00089 NODE * q;
00090 NODE * curr_defn;
00091 NODE * prev_defn;
00092 NODE * args;
00093
00094 if (id -> id_def_found) return(SUCCESS);
00095 if (id -> sel_type == NIL) {
00096 curr_defn = id -> id_last_definition;
00097 while( curr_defn != NIL ) {
00098 q = declsig(curr_defn);
00099 if (declerr != SUCCESS) {
00100 if (may_fail || prev_def(curr_defn) != NIL) {
00101 return(declerr);
00102 } else {
00103
00104 id -> id_last_definition = curr_defn;
00105 id -> id_def_found = TRUE;
00106 return(SUCCESS);
00107 }
00108 }
00109 if(def_match(q, id -> signature, appl, id, exact)) {
00110 id -> id_last_definition = curr_defn;
00111 id -> id_def_found = TRUE;
00112 # ifdef TRACE
00113 unparse_file = stdout;
00114 printf("Found definition for ");
00115 unparse(id);
00116 printf("\n");
00117 # endif
00118
00119 if (curr_defn -> kind == DECLARATION
00120 && (prev_defn = prev_def(curr_defn)) != NIL
00121 && prev_defn -> kind == DECLARATION
00122 && curr_defn -> decl_scope == prev_defn -> decl_scope) {
00123 q = declsig(prev_defn);
00124 if (declerr == SUCCESS && q != ERR_SIG &&
00125 def_match(q, id -> signature, appl, id, exact)) {
00126 extern int yynerrs;
00127 errmsg1(id, "Ambiguous reference to %s",
00128 getname(id -> id_str_table_index));
00129 }
00130 }
00131 return(SUCCESS);
00132 } else {
00133 # ifdef TRACE
00134 unparse_file = stdout;
00135 printf("Def_match failed for ");
00136 unparse(id);
00137 printf("\nDeclaration sig:");
00138 unparse(q);
00139 printf("\n");
00140 # endif
00141 curr_defn = prev_def(curr_defn);
00142 }
00143 }
00144 if (appl != NIL) {
00145
00146 args = appl -> ap_args;
00147 # ifdef DEBUG
00148 if (appl -> kind != APPLICATION) {
00149 dbgmsg("finndecl1: bad application\n");
00150 abort();
00151 }
00152 # endif
00153 begin_maplist(p, args) {
00154 NODE * arg_sig = p -> signature;
00155
00156 NODE * arg_type;
00157
00158 if (arg_sig == ERR_SIG) continue;
00159 IFDEBUG(
00160 if (arg_sig == NIL) {
00161 dbgmsg("finddecl: unknown arg signature\n");
00162 abort();
00163 }
00164 )
00165 if (arg_sig -> kind == FUNCSIGNATURE) {
00166 arg_sig = arg_sig -> fsig_result_sig;
00167 if (arg_sig == ERR_SIG) continue;
00168 }
00169 if (arg_sig -> kind == VALSIGNATURE) {
00170 arg_type = arg_sig -> val_denotation;
00171 } else if (arg_sig -> kind == VARSIGNATURE) {
00172 arg_type = arg_sig -> var_denotation;
00173 } else {
00174 continue;
00175 }
00176
00177 if(arg_type -> kind == MODPRIMARY
00178 && arg_type -> mp_type_modifier == NIL) {
00179 arg_type = arg_type -> mp_primary;
00180 }
00181 if((q = findsig(arg_type, FALSE)) != SUCCESS) {
00182 if (!may_fail ||
00183 (length(args) == 1 ||
00184 comp_st(first(args) -> signature, last(args) -> signature,
00185 NIL, NIL) == 0)) {
00186
00187 initfld(&(id -> sel_type), unshare(arg_type));
00188 id -> id_def_found = TRUE;
00189 return(SUCCESS);
00190 } else {
00191 return(q);
00192 }
00193 }
00194 IFDEBUG(
00195 if(arg_type -> signature == NIL) {
00196 dbgmsg("finddecl: no type signature\n");
00197 prtree(arg_type);
00198 printf("sig_done = %d\n", arg_type -> sig_done);
00199 }
00200 )
00201 if (arg_type -> signature == ERR_SIG) {
00202 continue;
00203 }
00204 if (arg_type -> signature -> kind == TYPESIGNATURE) {
00205 q = getcomp(arg_type -> signature,
00206 id,
00207 arg_type,
00208 id -> signature, NIL,
00209 appl, exact);
00210 } else {
00211
00212 q = NIL;
00213 }
00214 if (q != NIL) {
00215 initsig(id, q);
00216 initfld(&(id -> sel_type), unshare(arg_type));
00217 id -> id_def_found = TRUE;
00218 id -> sel_index = comp_index;
00219 id -> sig_done = SIG_DONE;
00220 return(SUCCESS);
00221 }
00222 } end_maplist;
00223 }
00224
00225 usl = id -> id_use_list;
00226 while(usl != NIL) {
00227 # ifdef DEBUG
00228 if (usl -> kind != USELIST) {
00229 dbgmsg("finddecl: bad use list\n");
00230 }
00231 # endif
00232 maplist(p, usl -> usl_type_list, {
00233 IFDEBUG(
00234 if (p -> signature == NIL) {
00235 dbgmsg("finddecl: use list type without sig\n");
00236 prtree(p);
00237 }
00238 )
00239 if (p -> signature == ERR_SIG
00240 || p -> signature -> kind == TYPESIGNATURE)
00241 q = getcomp(p -> signature,
00242 id,
00243 p,
00244 id -> signature, NIL,
00245 appl, exact);
00246 else
00247
00248 q = NIL;
00249 if (q != NIL) {
00250 initsig(id, q);
00251 initfld(&(id -> sel_type), unshare(p));
00252 id -> id_def_found = TRUE;
00253 id -> sel_index = comp_index;
00254 id -> sig_done = SIG_DONE;
00255 return(SUCCESS);
00256 }
00257 });
00258 usl = usl -> usl_previous_list;
00259 }
00260
00261
00262 return(SUCCESS);
00263 } else {
00264 id -> id_def_found = TRUE;
00265 return(SUCCESS);
00266 }
00267 }
00268
00269
00270
00271
00272
00273
00274
00275
00276 NODE *
00277 findstdecl(string)
00278 NODE * string;
00279 {
00280 NODE * usl;
00281 boolean found_it = 0;
00282 NODE * q;
00283
00284 if (string -> sel_type == NIL) {
00285
00286 usl = string -> str_use_list;
00287 while(usl != NIL && !found_it) {
00288 # ifdef DEBUG
00289 if (usl -> kind != USELIST) {
00290 dbgmsg("finddecl: bad use list\n");
00291 }
00292 # endif
00293 maplist(p, usl -> usl_type_list, {
00294 IFDEBUG(
00295 if (p -> signature == NIL) {
00296 dbgmsg("finddecl: use list type without sig\n");
00297 }
00298 )
00299 if (p -> signature == ERR_SIG) {
00300 found_it = TRUE;
00301 } else if (p -> signature -> kind == TYPESIGNATURE) {
00302 found_it = hasstring(p -> signature, string);
00303 } else {
00304
00305 found_it = FALSE;
00306 }
00307 if(found_it) {
00308 initfld(&(string -> sel_type), unshare(p));
00309 break;
00310 }
00311 });
00312 usl = usl -> usl_previous_list;
00313 }
00314 } else {
00315 if ((q = findsig(string -> sel_type, FALSE)) != SUCCESS) {
00316 return(q);
00317 }
00318 if (string -> sel_type -> signature == ERR_SIG) {
00319 return(SUCCESS);
00320 }
00321 if (!hasstring(string -> sel_type -> signature, string)) {
00322 chgfld(&(string -> sel_type), NIL);
00323 }
00324 }
00325 return(SUCCESS);
00326 }
00327
00328
00329
00330
00331
00332
00333
00334
00335 NODE *
00336 prev_def(def)
00337 NODE * def;
00338 {
00339 switch(def -> kind) {
00340 case DECLARATION:
00341 return(def -> decl_previous_definition);
00342 case PARAMETER:
00343 return(def -> par_previous_definition);
00344 case TYPESIGNATURE:
00345 return(def -> ts_previous_definition);
00346 case PRODCONSTRUCTION:
00347 case UNIONCONSTRUCTION:
00348 return(def -> prod_previous_definition);
00349 case RECORDCONSTRUCTION:
00350 return(def -> rec_previous_definition);
00351 case MODPRIMARY:
00352 switch (def -> mp_type_modifier -> kind) {
00353 case WITHLIST:
00354 return(def -> mp_type_modifier -> wl_previous_definition);
00355 case EXPORTLIST:
00356 case HIDELIST:
00357 return(def -> mp_type_modifier -> el_previous_definition);
00358 # ifdef DEBUG
00359 default:
00360 dbgmsg("prev_def: bad type modifier\n");
00361 # endif
00362 }
00363 # ifdef DEBUG
00364 default:
00365 dbgmsg("prev_def: bad definition field\n");
00366 # endif
00367 }
00368 }
00369
00370
00371
00372
00373
00374
00375
00376 NODE * sig_structure(sig)
00377 NODE * sig;
00378 {
00379 NODE * result = sig;
00380
00381 while (result -> kind == LETTERID || result -> kind == OPRID
00382 && result -> id_last_definition -> kind == DECLARATION
00383 && result -> id_last_definition -> decl_sig_transp) {
00384 result = result -> id_last_definition -> decl_denotation;
00385 }
00386 return(result);
00387 }
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401 boolean
00402 def_match( sig, sig2, appl, op, exact )
00403 NODE * sig, * sig2, * appl;
00404 NODE * op;
00405 boolean exact;
00406 {
00407 register NODE * arg_sig;
00408 NODE * args;
00409 NODE * void_decl;
00410 NODE * arg_type;
00411 NODE * new_args;
00412 int num_args, num_params;
00413
00414 if (appl != NIL) {
00415 # ifdef DEBUG
00416 if (appl -> kind != APPLICATION) {
00417 dbgmsg("def_match: bad application\n");
00418 abort();
00419 }
00420 # endif
00421 args = appl -> ap_args;
00422 void_decl = appl -> ap_void_decl;
00423 } else {
00424 args = NIL;
00425 void_decl = NIL;
00426 }
00427 if (sig == ERR_SIG)
00428 return(TRUE);
00429 if (sig -> kind == LETTERID || sig -> kind == OPRID) {
00430 # ifdef TRACE
00431 printf("Replacing signature transparent identifier\n");
00432 # endif
00433 sig = sig_structure(sig);
00434 }
00435 if (sig2 != NIL && sig2 != ERR_SIG && comp_st(sig, sig2, NIL, NIL) != 0) {
00436 # ifdef TRACE
00437 printf("Failed to match explicit signature\n");
00438 # endif
00439 return(FALSE);
00440 }
00441 if (args == NIL)
00442 return(TRUE);
00443 if (sig -> kind != FUNCSIGNATURE) {
00444 # ifdef TRACE
00445 printf("Non-function id with a specified application\n");
00446 # endif
00447 return(FALSE);
00448 }
00449 num_args = length(args);
00450 num_params = length(sig -> fsig_param_list);
00451 if (num_args < num_params) {
00452 new_args = infer_args(args,
00453 sig -> fsig_param_list,
00454 void_decl, op);
00455 # ifdef TRACE
00456 printf("Inferred arguments\n");
00457 # endif
00458 } else {
00459 new_args = args;
00460 }
00461 if (num_args > num_params ||
00462 num_args < num_params && new_args == NIL) {
00463 # ifdef TRACE
00464 printf("Incorrect number of arguments\n");
00465 # endif
00466 return(FALSE);
00467 }
00468 begin_map2lists(p, new_args, q, sig -> fsig_param_list) {
00469 NODE * par_sig = q -> par_signature;
00470 NODE * s_par_sig;
00471
00472 s_par_sig = subst(par_sig,
00473 sig -> fsig_param_list,
00474 new_args);
00475 arg_sig = p -> signature;
00476 if (arg_sig == ERR_SIG || s_par_sig == ERR_SIG) {
00477 if (s_par_sig != NIL && s_par_sig != ERR_SIG) {
00478 vfree(s_par_sig);
00479 }
00480 return(TRUE);
00481 }
00482
00483
00484
00485 if (!exact) {
00486 if (s_par_sig -> kind == LETTERID || s_par_sig -> kind == OPRID) {
00487 s_par_sig = sig_structure(s_par_sig);
00488 # ifdef TRACE
00489 unparse_file = stdout;
00490 printf("Changed parameter signature to ");
00491 unparse(s_par_sig);
00492 printf("\n");
00493 # endif
00494 }
00495 }
00496 lock(s_par_sig);
00497 if (exact || s_par_sig -> kind != VALSIGNATURE) {
00498 if (!amatch(arg_sig, s_par_sig)) {
00499 vfree(unlock(s_par_sig));
00500 # ifdef TRACE
00501 printf("Failed exact match\n");
00502 # endif
00503 return(FALSE);
00504 }
00505 } else {
00506 if (arg_sig -> kind == LETTERID || arg_sig -> kind == OPRID) {
00507 arg_sig = sig_structure(arg_sig);
00508 # ifdef TRACE
00509 unparse_file = stdout;
00510 printf("Changed argument signature to ");
00511 unparse(arg_sig);
00512 printf("\n");
00513 # endif
00514 }
00515 switch (arg_sig -> kind) {
00516 case TYPESIGNATURE:
00517 vfree(unlock(s_par_sig));
00518 # ifdef TRACE
00519 printf("Attempted val-type match\n");
00520 # endif
00521 return(FALSE);
00522 case FUNCSIGNATURE:
00523 if (!is_empty(arg_sig -> fsig_param_list)) {
00524 vfree(unlock(s_par_sig));
00525 # ifdef TRACE
00526 printf("Application coercion failed - args\n");
00527 # endif
00528 return(FALSE);
00529 }
00530 if (comp_st(arg_sig -> fsig_result_sig,
00531 s_par_sig, NIL, NIL) != 0) {
00532 vfree(unlock(s_par_sig));
00533 # ifdef TRACE
00534 printf("Application coercion failed - result\n");
00535 # endif
00536 return(FALSE);
00537 }
00538 break;
00539 case VARSIGNATURE:
00540 if (comp_st(arg_sig -> var_denotation,
00541 s_par_sig -> val_denotation, NIL, NIL) != 0) {
00542 vfree(unlock(s_par_sig));
00543 # ifdef TRACE
00544 printf("ValueOf coercion failed\n");
00545 # endif
00546 return(FALSE);
00547 }
00548 break;
00549 case VALSIGNATURE:
00550 if (comp_st(arg_sig -> val_denotation,
00551 s_par_sig -> val_denotation, NIL, NIL) != 0) {
00552 vfree(unlock(s_par_sig));
00553 # ifdef TRACE
00554 {
00555 extern NODE * diff_p, * diff_q;
00556 printf("Val signature comparison failed with diff_p = ");
00557 unparse_file = stdout;
00558 unparse(diff_p);
00559 printf("; diff_q = ");
00560 unparse(diff_q);
00561 printf("\n");
00562 }
00563 # endif
00564 return(FALSE);
00565 }
00566 break;
00567 IFDEBUG(
00568 default:
00569 dbgmsg("def_match: bad argument signature:%X\n", arg_sig);
00570 prtree(p);
00571 abort();
00572 )
00573 }
00574 }
00575 vfree(unlock(s_par_sig));
00576 }end_map2lists;
00577 return(TRUE);
00578 }