00001 # define TRACE
00002 # undef TRACE
00003 # define DEBUG
00004
00005 # include <stdio.h>
00006 # include "parm.h"
00007
00008 # include "stree/ststructs.mh"
00009
00010 # include "stree/stsigs.mh"
00011
00012 # include "sigs.h"
00013
00014 # include "pass3/decl_pairs.h"
00015 # include "pass3/is_local.h"
00016
00017 extern unsigned stplinks[];
00018
00019 extern int stsize[];
00020
00021 extern int yynerrs;
00022
00023 extern struct cn * dontsubst;
00024
00025 extern NODE * substerr;
00026
00027 extern FILE * unparse_file;
00028
00029
00030
00031
00032 NODE * on_dontsubst(s)
00033 NODE *s;
00034 {
00035 struct cn *c;
00036
00037 c = dontsubst;
00038 while(c != NIL) {
00039 if( is_descendant(((NODE *)(cn_head(c))), s) ) {
00040 # ifdef TRACE
00041 printf("on_dontsubst: returning 0x%X\n", cn_head(c));
00042 fflush(stdout);
00043 # endif
00044 return((NODE *)(cn_head(c)));
00045 }
00046 c = cn_tail(c);
00047 };
00048 return(NIL);
00049 }
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067 NODE * subst1();
00068
00069 NODE * subst(p,params,args)
00070 NODE * p, * params, * args;
00071 {
00072 NODE * result;
00073
00074 if (is_empty(params)) {
00075 return(p);
00076 }
00077 clr_dlist;
00078 result = subst1(p, params, args);
00079 # ifdef TRACE
00080 if (result != p) {
00081 unparse_file = stdout;
00082 printf("subst: replaced\n");
00083 unparse(p);
00084 printf("\nwith\n");
00085 unparse(result);
00086 printf("\n");
00087 }
00088 # endif
00089 return(result);
00090 }
00091
00092 NODE * subst1(p,params,args)
00093 NODE * p, *params, *args;
00094 {
00095 boolean mod_flag = FALSE;
00096 register int knd;
00097 int plinkv;
00098
00099
00100 int sigv;
00101 register NODE ** q;
00102
00103 int idpos;
00104 NODE * tmpcopy[MAXFIELDS];
00105 register NODE ** s;
00106 register int i;
00107 int lim;
00108 register struct cn * c;
00109 int j;
00110 NODE * v, * w;
00111
00112 if (p == ERR_SIG || p == NIL) return(p);
00113
00114 switch ( knd = (p -> kind) ) {
00115 case LISTHEADER:
00116 i = 0;
00117 j = length(p);
00118
00119
00120 if (j <= MAXFIELDS) {
00121 s = tmpcopy;
00122 } else {
00123 s = (NODE **) malloc(j * sizeof(NODE *));
00124 }
00125 maplist(q, p, {
00126 s[i] = subst1(q, params, args);
00127
00128 if(s[i] != q) {
00129 mod_flag = TRUE;
00130 }
00131 i++;
00132 });
00133 if (mod_flag) {
00134
00135
00136 NODE * result;
00137 result = emptylist();
00138 for (i = 0; i < j; i++) {
00139 addright(result,s[i]);
00140 }
00141 if (j > MAXFIELDS) free(s);
00142 return(result);
00143 } else {
00144 if (j > MAXFIELDS) free(s);
00145 return(p);
00146 }
00147 case OPRID:
00148 case LETTERID:
00149 if (p -> id_str_table_index == -1) return(p);
00150 # ifdef DEBUG
00151 if (!(p -> id_def_found) && yynerrs == 0) {
00152 dbgmsg("subst: id declaration unresolved: %s\n",
00153 getname(p -> id_str_table_index));
00154 }
00155 # endif
00156 if (!p -> id_def_found) {
00157
00158 return(p);
00159 }
00160 if (p -> sel_type != NIL) {
00161 NODE * new_sel_type = subst1(p -> sel_type, params, args);
00162
00163 if (new_sel_type == p -> sel_type) {
00164
00165
00166 return(p);
00167 } else {
00168 NODE * q = copynode(p);
00169 q -> sig_done = SIG_UNKNOWN;
00170 chgfld(&(q -> signature), NIL);
00171 chgfld(&(q -> sel_type), new_sel_type);
00172 q -> id_appl = NIL;
00173 return(q);
00174 }
00175 }
00176
00177
00178
00179
00180 i = 0;
00181 idpos = 0;
00182 if (p -> id_last_definition -> kind == PARAMETER) {
00183 maplist(s, params, {
00184 i++;
00185 if(is_declared_by(p,s)) {
00186 idpos = i;
00187 }
00188 });
00189 } else if (p -> id_last_definition != NIL
00190 && p -> id_last_definition -> kind == DECLARATION
00191 && p -> id_last_definition -> decl_sig_transp) {
00192 NODE * tmp = subst1(p -> id_last_definition -> decl_denotation,
00193 params, args);
00194 if (tmp != p -> id_last_definition -> decl_denotation) {
00195 return(tmp);
00196 }
00197
00198
00199 }
00200 if (idpos != 0) {
00201
00202 i = 0;
00203 maplist(s, args, {
00204 i++;
00205 if(i == idpos) {
00206
00207
00208 if (on_dontsubst(s) != NIL) {
00209 substerr = on_dontsubst(s);
00210 }
00211 return(s);
00212 }
00213 });
00214 } else {
00215 if (dl_new_decl(p) != p -> id_last_definition) {
00216
00217 NODE * q = copynode(p);
00218 q -> id_last_definition = dl_new_decl(p);
00219 if (q -> signature != ERR_SIG) {
00220 q -> sig_done = SIG_UNKNOWN;
00221 chgfld(&(q -> signature), NIL);
00222 }
00223 q -> id_appl = NIL;
00224 return(q);
00225 } else {
00226
00227
00228 return(p);
00229 }
00230 }
00231
00232 case MODPRIMARY:
00233
00234 if (p -> mp_type_modifier == NIL) {
00235
00236 return (subst1(p -> mp_primary, params, args));
00237 }
00238 v = copynode(p);
00239 add_dlist(p, v);
00240 chgfld(&(v -> mp_primary), subst1(p -> mp_primary, params, args));
00241 chgfld(&(v -> mp_type_modifier),
00242 subst1(p -> mp_type_modifier, params, args));
00243 if (p -> mp_primary == v -> mp_primary &&
00244 p -> mp_type_modifier == v -> mp_type_modifier) {
00245 return(v);
00246 } else if (p -> signature != ERR_SIG) {
00247 chgfld(&(v -> signature), NIL);
00248 v -> sig_done = SIG_UNKNOWN;
00249 }
00250 return(v);
00251
00252 case RECORDCONSTRUCTION:
00253
00254 v = copynode(p);
00255 add_dlist(p, v);
00256 chgfld(&(v -> rec_component_list),
00257 subst1(p -> rec_component_list, params, args));
00258 if (p -> signature != ERR_SIG) {
00259 chgfld(&(v -> signature), NIL);
00260 v -> sig_done = SIG_UNKNOWN;
00261 }
00262 return(v);
00263
00264 case UNIONCONSTRUCTION:
00265
00266 v = copynode(p);
00267 add_dlist(p, v);
00268 chgfld(&(v -> prod_components),
00269 subst1(p -> prod_components, params, args));
00270 if (p -> signature != ERR_SIG) {
00271 chgfld(&(v -> signature), NIL);
00272 v -> sig_done = SIG_UNKNOWN;
00273 }
00274 return(v);
00275
00276 case PRODCONSTRUCTION:
00277
00278 {
00279 NODE * new_prod = copynode(p);
00280 NODE * new_params = emptylist();
00281
00282
00283 maplist(s, p -> prod_components, {
00284 v = copynode(s);
00285 add_dlist(s, v);
00286 addright(new_params, v);
00287 });
00288
00289 maplist(s, new_params, {
00290 chgfld(&(s -> par_signature),
00291 subst1(s -> par_signature, params, args));
00292 });
00293
00294 chgfld(&(new_prod -> prod_components), new_params);
00295 if (new_prod -> signature != ERR_SIG) {
00296 chgfld(&(new_prod -> signature), NIL);
00297 new_prod -> sig_done = SIG_UNKNOWN;
00298 }
00299 return(new_prod);
00300 }
00301
00302 case TYPESIGNATURE:
00303
00304 v = copynode(p);
00305 add_dlist(p, v);
00306 chgfld(&(v -> ts_clist),
00307 subst1(p -> ts_clist, params, args));
00308 return(v);
00309
00310
00311
00312
00313
00314 case TSCOMPONENT:
00315 v = subst1(p -> tsc_signature, params, args);
00316 if (v != p -> tsc_signature) {
00317 w = copynode(p);
00318 chgfld(&(w -> tsc_signature), v);
00319 return(w);
00320 } else {
00321 return(p);
00322 }
00323
00324 case WITHLIST:
00325
00326 v = subst1(p -> wl_component_list, params, args);
00327 if (v != p -> wl_component_list) {
00328 w = copynode(p);
00329 chgfld(&(w -> wl_component_list), v);
00330 return(w);
00331 } else {
00332 return(p);
00333 }
00334
00335 case EXPORTLIST:
00336 case HIDELIST:
00337 v = subst1(p -> el_export_element_list, params, args);
00338 if (v != p -> el_export_element_list) {
00339 w = copynode(p);
00340 chgfld(&(w -> el_export_element_list), v);
00341 return(w);
00342 } else {
00343 return(p);
00344 }
00345
00346
00347 case RECORDELEMENT:
00348 v = subst1(p -> re_denotation, params, args);
00349 if (v != p -> re_denotation) {
00350 w = copynode(p);
00351 chgfld(&(w -> re_denotation), v);
00352 return(w);
00353 } else {
00354 return(p);
00355 }
00356
00357 case PARAMETER:
00358 v = subst1(p -> par_signature, params, args);
00359 if (v != p -> par_signature) {
00360 w = copynode(p);
00361 chgfld(&(w -> par_signature), v);
00362 return(w);
00363 } else {
00364 return(p);
00365 }
00366
00367 case DECLARATION:
00368 { NODE * new_sig, * new_den;
00369
00370 new_sig = subst1(p -> decl_signature, params, args);
00371 new_den = subst1(p -> decl_denotation, params, args);
00372 if (new_sig != p -> decl_signature
00373 || new_den != p -> decl_denotation) {
00374 w = copynode(p);
00375 chgfld(&(w -> decl_signature), new_sig);
00376 chgfld(&(w -> decl_denotation), new_den);
00377 return(w);
00378 } else {
00379 return(p);
00380 }
00381 }
00382
00383
00384
00385
00386
00387
00388 case BLOCKDENOTATION:
00389 {
00390 NODE * new_block = copynode(p);
00391 NODE * new_decls = emptylist();
00392
00393
00394 maplist(s, p -> bld_declaration_list, {
00395 v = copynode(s);
00396 add_dlist(s, v);
00397 addright(new_decls, v);
00398 });
00399
00400 maplist(s, new_decls, {
00401 chgfld(&(s -> decl_signature),
00402 subst1(s -> decl_signature, params, args));
00403 chgfld(&(s -> decl_denotation),
00404 subst1(s -> decl_denotation, params, args));
00405 });
00406
00407 chgfld(&(new_block -> bld_den_seq),
00408 subst1(p -> bld_den_seq, params, args));
00409 chgfld(&(new_block -> bld_declaration_list), new_decls);
00410
00411 if (new_block -> signature != ERR_SIG) {
00412 chgfld(&(new_block -> signature), NIL);
00413 new_block -> sig_done = SIG_UNKNOWN;
00414 }
00415 return(new_block);
00416 }
00417
00418 case FUNCCONSTR:
00419
00420
00421
00422
00423
00424
00425
00426
00427 if (!is_empty(p -> signature -> fsig_param_list)
00428 && first(params) -> pre_num ==
00429 first(p -> signature -> fsig_param_list) -> pre_num) {
00430 # ifdef TRACE
00431 printf("Truncating substitution\n");
00432 # endif
00433 return(p);
00434 }
00435 {
00436 NODE * new_func = copynode(p);
00437 NODE * new_sig = copynode(p -> signature);
00438 NODE * new_params = emptylist();
00439
00440
00441 maplist(s, p -> signature -> fsig_param_list, {
00442 v = copynode(s);
00443 add_dlist(s, v);
00444 addright(new_params, v);
00445 });
00446
00447 maplist(s, new_params, {
00448 chgfld(&(s -> par_signature),
00449 subst1(s -> par_signature, params, args));
00450 });
00451
00452 if (new_sig -> fsig_result_sig != ERR_SIG) {
00453 chgfld(&(new_sig -> fsig_result_sig),
00454 subst1(new_sig -> fsig_result_sig, params, args));
00455 }
00456 chgfld(&(new_sig -> fsig_param_list), new_params);
00457 chgfld(&(new_func -> fc_body),
00458 subst1(p -> fc_body, params, args));
00459 chgfld(&(new_func -> signature), new_sig);
00460 return(new_func);
00461 }
00462
00463 case FUNCSIGNATURE:
00464 {
00465 NODE * new_sig = copynode(p);
00466 NODE * new_params = emptylist();
00467
00468
00469 maplist(s, p -> fsig_param_list, {
00470 v = copynode(s);
00471 add_dlist(s, v);
00472 addright(new_params, v);
00473 });
00474
00475 maplist(s, new_params, {
00476 chgfld(&(s -> par_signature),
00477 subst1(s -> par_signature, params, args));
00478 });
00479
00480 if (new_sig -> fsig_result_sig != ERR_SIG) {
00481 chgfld(&(new_sig -> fsig_result_sig),
00482 subst1(new_sig -> fsig_result_sig, params, args));
00483 }
00484 chgfld(&(new_sig -> fsig_param_list), new_params);
00485 return(new_sig);
00486 }
00487
00488 default:
00489 deflt:
00490 i = 0;
00491 q = (NODE **) p;
00492 sigv = stsigs[knd];
00493 plinkv = stplinks[knd];
00494 lim = stsize[knd];
00495 for(; i < lim;
00496 (plinkv <<= 1, sigv <<= 1, q++, i++)) {
00497 if (plinkv < 0 && sigv >= 0 ) {
00498 tmpcopy[i] = subst1(*q, params, args);
00499
00500 if(tmpcopy[i] != *q) {
00501 mod_flag = TRUE;
00502 }
00503 } else {
00504 tmpcopy[i] = *q;
00505
00506 }
00507 }
00508 if (mod_flag) {
00509
00510 for((sigv = stsigs[knd], i = 0); sigv != 0;
00511 (sigv <<= 1, i++)) {
00512 if (sigv < 0) {
00513 tmpcopy[i] = 0;
00514 tmpcopy[i+1] = SIG_UNKNOWN;
00515 }
00516 }
00517 return(copynode((NODE *)tmpcopy));
00518 } else {
00519 return(p);
00520 }
00521 }
00522 }
00523
00524
00525
00526
00527
00528 boolean trivial(p)
00529 NODE * p;
00530 {
00531 switch(p -> kind) {
00532 case LETTERID:
00533 case OPRID:
00534 if (!p -> id_def_found) {
00535 return(FALSE);
00536 }
00537 if (p -> sel_type == NIL) {
00538 return(TRUE);
00539 } else {
00540 return(trivial(p -> sel_type));
00541 }
00542 default:
00543 return(FALSE);
00544 }
00545 }
00546
00547
00548
00549
00550
00551
00552
00553 NODE * unshare1();
00554
00555 NODE * unshare(p)
00556 NODE * p;
00557 {
00558 NODE * result;
00559
00560 clr_dlist;
00561 result = unshare1(p);
00562 return(result);
00563 }
00564
00565 NODE * unshare1(p)
00566 NODE * p;
00567 {
00568 boolean mod_flag = FALSE;
00569 register int knd;
00570 int plinkv;
00571
00572
00573 int sigv;
00574 register NODE ** q;
00575
00576 NODE * tmpcopy[MAXFIELDS];
00577 register NODE ** s;
00578 register int i;
00579 int lim;
00580 register struct cn * c;
00581 int j;
00582 NODE * v, * w;
00583
00584
00585 if (p == NIL) { return(NIL); }
00586
00587 knd = p -> kind;
00588 switch(knd) {
00589 case LISTHEADER:
00590 i = 0;
00591 j = length(p);
00592
00593
00594 if (j <= MAXFIELDS) {
00595 s = tmpcopy;
00596 } else {
00597 s = (NODE **) malloc(j * sizeof(NODE *));
00598 }
00599 maplist(q, p, {
00600 s[i] = unshare1(q);
00601
00602 if(s[i] != q) {
00603 mod_flag = TRUE;
00604 }
00605 i++;
00606 });
00607 if (mod_flag) {
00608
00609
00610 NODE * result;
00611 result = emptylist();
00612 for (i = 0; i < j; i++) {
00613 addright(result,s[i]);
00614 }
00615 if (j > MAXFIELDS) free(s);
00616 return(result);
00617 } else {
00618 if (j > MAXFIELDS) free(s);
00619 return(p);
00620 }
00621
00622 case FUNCCONSTR:
00623
00624 {
00625 NODE * new_func = copynode(p);
00626 NODE * new_sig = copynode(p -> signature);
00627 char * new_lbl = (char *) malloc(strlen(p -> fc_code_label)+8);
00628 char buf[7];
00629 static int fn_count = 0;
00630
00631 chgfld(&(new_sig -> fsig_param_list),
00632 unshare1(new_sig -> fsig_param_list));
00633 chgfld(&(new_func -> signature), new_sig);
00634 new_sig -> fsig_construction = new_func;
00635 chgfld(&(new_func -> fc_body), unshare1(p -> fc_body));
00636
00637
00638
00639 # ifdef DEBUG
00640 if (p -> fc_code_label == NIL) {
00641 dbgmsg("Unshare: missing label\n");
00642 abort();
00643 }
00644 # endif
00645 strcpy(new_lbl, p -> fc_code_label);
00646 sprintf(buf, ".%d", fn_count++);
00647 strcat(new_lbl, buf);
00648 new_func -> fc_code_label = new_lbl;
00649 return(new_func);
00650 }
00651
00652 case DECLARATION:
00653
00654 { NODE * new_sig, * new_den;
00655 extern NODE * clear_construction();
00656
00657 new_sig = clear_construction(p -> decl_signature);
00658 new_den = unshare1(p -> decl_denotation);
00659 w = copynode(p);
00660 chgfld(&(w -> decl_signature), new_sig);
00661 chgfld(&(w -> decl_denotation), new_den);
00662 w -> decl_sig_done = SIG_UNKNOWN;
00663 return(w);
00664 }
00665
00666 case PARAMETER:
00667
00668 v = copynode(p);
00669 add_dlist(p, v);
00670 return(v);
00671
00672 case BLOCKDENOTATION:
00673
00674 {
00675 NODE * new_block = copynode(p);
00676 NODE * new_decls = emptylist();
00677
00678
00679 maplist(s, p -> bld_declaration_list, {
00680 v = copynode(s);
00681 add_dlist(s, v);
00682 addright(new_decls, v);
00683 });
00684
00685 maplist(s, new_decls, {
00686 chgfld(&(s -> decl_denotation), unshare1(s -> decl_denotation));
00687 });
00688
00689 chgfld(&(new_block -> bld_den_seq), unshare1(p -> bld_den_seq));
00690 chgfld(&(new_block -> bld_declaration_list), new_decls);
00691
00692 new_block -> bld_flags &= ~NO_SURR_LOOP;
00693 return(new_block);
00694 }
00695
00696 case MODPRIMARY:
00697
00698 v = copynode(p);
00699 add_dlist(p,v);
00700 chgfld(&(v -> mp_primary), unshare1(p -> mp_primary));
00701 if (v -> mp_type_modifier != NIL) {
00702 chgfld(&(v -> mp_type_modifier), unshare1(p -> mp_type_modifier));
00703 }
00704 v -> mp_no_surr_loop = FALSE;
00705 return(v);
00706
00707 case PRODCONSTRUCTION:
00708 case UNIONCONSTRUCTION:
00709
00710 return(p);
00711
00712 case LETTERID:
00713 case OPRID:
00714 if (p -> sel_type == NIL) {
00715 if ((w = dl_new_decl(p)) != p -> id_last_definition) {
00716
00717 v = copynode(p);
00718 v -> id_last_definition = w;
00719 return(v);
00720 } else {
00721 return(p);
00722 }
00723 } else {
00724 v = unshare1(p -> sel_type);
00725 if (v != p -> sel_type) {
00726 w = copynode(p);
00727 chgfld(&(w -> sel_type), v);
00728 return(w);
00729 } else {
00730 return(p);
00731 }
00732 }
00733
00734 default:
00735 i = 0;
00736 q = (NODE **) p;
00737 sigv = stsigs[knd];
00738 plinkv = stplinks[knd];
00739 lim = stsize[knd];
00740 for(; i < lim;
00741 (plinkv <<= 1, sigv <<= 1, q++, i++)) {
00742 if (plinkv < 0 && sigv >= 0 ) {
00743 tmpcopy[i] = unshare1(*q);
00744
00745 if(tmpcopy[i] != *q) {
00746 mod_flag = TRUE;
00747 }
00748 } else {
00749 tmpcopy[i] = *q;
00750
00751 }
00752 }
00753 if (mod_flag) {
00754 # ifdef VERBOSE
00755 printf("Unshare copied node: ");
00756 unparse_file = stdout;
00757 unparse(p);
00758 printf("\n");
00759 # endif
00760
00761 for((sigv = stsigs[knd], i = 0); sigv != 0;
00762 (sigv <<= 1, i++)) {
00763 if (sigv < 0) {
00764 extern NODE * clear_construction();
00765 NODE * s = tmpcopy[i];
00766
00767 tmpcopy[i] = clear_construction(s);
00768 }
00769 }
00770 return(copynode((NODE *)tmpcopy));
00771 } else {
00772 return(p);
00773 }
00774 }
00775 }