00001 # define TRACE
00002 # undef TRACE
00003 # define DEBUG
00004
00005 # define TRACE2
00006 # undef TRACE2
00007
00008 # ifdef DEBUG
00009 # define IFDEBUG(x) x
00010 # else
00011 # define IFDEBUG(x)
00012 # endif
00013
00014 # include <stdio.h>
00015 # include "parm.h"
00016 # include "arith.h"
00017
00018 # include "stree/ststructs.mh"
00019 # ifdef DEBUG
00020 # include "stree/is_ptr.h"
00021 # endif
00022
00023 # include "sigs.h"
00024
00025 # include "stree/Array.h"
00026
00027
00028 # include "pass1/stt/sttdefs.h"
00029
00030 extern FILE * unparse_file;
00031
00032 extern boolean Gflag;
00033
00034 extern boolean Nflag;
00035
00036 # define UNDEFNAME ((sttrelptr) 0)
00037
00038 extern sttrelptr indx_New,
00039 indx_ValueOf,
00040 indx_assign,
00041 indx_equals,
00042 indx_ne,
00043 indx_Mk,
00044 indx_First,
00045 indx_Last,
00046 indx_Pred,
00047 indx_Succ,
00048 indx_Ord,
00049 indx_OrdInv,
00050 indx_Card,
00051 indx_In,
00052 indx_Out;
00053
00054 extern NODE * sig_New,
00055 * sig_ValueOf,
00056 * sig_assign,
00057 * sig_equals,
00058 * sig_const,
00059 * val_Boolean,
00060 * val_Integer,
00061 * val_Void,
00062 * sig_Signature;
00063
00064
00065
00066 # define init_inline(r) \
00067 (r) -> tsc_signature -> fsig_inline_code = \
00068 (*spcl_to_inline)((r) -> tsc_signature -> fsig_special);
00069
00070 extern int yynerrs;
00071
00072 extern int next_pre;
00073
00074
00075 # define ERR_NODE_DEFINED
00076 extern NODE * err_node;
00077
00078 extern char * err_msg;
00079
00080 extern NODE * curr_tsig;
00081
00082
00083 NODE * declerr;
00084
00085 NODE * substerr;
00086
00087
00088
00089
00090
00091 extern int match_len;
00092 extern unsigned * match_delv;
00093
00094
00095 extern NODE * failed_asig;
00096 extern NODE * failed_psig;
00097 extern NODE * failed_comp;
00098
00099 struct cn * dontsubst = NIL;
00100
00101
00102
00103 extern int comp_index;
00104
00105 # ifdef VAX
00106 int nargs();
00107 # endif
00108
00109 void find_inline();
00110
00111 void Gfind_inline();
00112
00113 boolean may_fail = FALSE;
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151 # define err_return \
00152 p -> signature = ERR_SIG; \
00153 p -> sig_done = SIG_DONE; \
00154 return(SUCCESS);
00155
00156 # ifdef DEBUG
00157 NODE * return_val;
00158 # define return(p) { return_val = p; goto findsig_out; }
00159 # endif
00160
00161 NODE * findsig(p, dont_coerce)
00162 register NODE * p;
00163 boolean dont_coerce;
00164 {
00165 register int knd;
00166 register int status = p -> sig_done;
00167 NODE * q, * r;
00168 boolean all_ok;
00169
00170
00171 # ifdef DEBUG
00172 # ifdef VAX
00173 if(nargs() != 2) {
00174 dbgmsg("findsig: wrong number of args\n");
00175 abort();
00176 }
00177 # endif
00178 # endif
00179 # ifdef DEBUG
00180 if (p == (NODE *)0x40404040) abort();
00181
00182 # endif
00183 if (status == SIG_DONE)
00184 return(SUCCESS);
00185 if (status == SIG_IN_PROGRESS ) {
00186 return(p);
00187 }
00188 knd = p -> kind;
00189 # ifdef DEBUG
00190 if ( p -> signature != NIL
00191 && knd != OPRID && knd != LETTERID && knd != FUNCCONSTR ) {
00192 dbgmsg("findsig: bad sig_done value, knd = %s, sig:\n",
00193 kindname(knd));
00194 prtree(p);
00195 prtree(p -> signature);
00196 abort();
00197 }
00198 # endif
00199
00200 p -> sig_done = SIG_IN_PROGRESS;
00201 switch(knd) {
00202 case OPRID:
00203 case LETTERID:
00204 return(findidsig(p));
00205
00206 case VALSIGNATURE:
00207 case VARSIGNATURE:
00208 case FUNCSIGNATURE:
00209 case TYPESIGNATURE:
00210 case SIGNATURESIG:
00211 initsig(p, sig_Signature);
00212 p -> sig_done = SIG_DONE;
00213 return(SUCCESS);
00214
00215 case FUNCCONSTR:
00216 # ifdef DEBUG
00217 if(p -> signature == NIL) {
00218
00219
00220 dbgmsg("NIL FUNCCONSTR signature\n");
00221 abort();
00222 }
00223 # endif
00224 q = p -> signature -> fsig_result_sig;
00225 if (q == NIL ) {
00226 if ((r = findsig(p -> fc_body,FALSE)) != SUCCESS) {
00227 p -> sig_done = SIG_UNKNOWN;
00228 return(r);
00229 }
00230 if(p -> fc_body -> signature != ERR_SIG) {
00231 initfld(&(p -> signature -> fsig_result_sig),
00232 p -> fc_body -> signature);
00233 if (Gflag) {
00234 Gfind_inline(p);
00235 } else {
00236 find_inline(p);
00237 }
00238 } else {
00239 p -> signature -> fsig_result_sig = ERR_SIG;
00240 }
00241 p -> sig_done = SIG_DONE;
00242 return(SUCCESS);
00243 } else {
00244
00245 boolean old_may_fail = may_fail;
00246 boolean is_void = comp_st(val_Void, q, NIL, NIL) == 0;
00247
00248 if (p -> fc_body -> kind == EXTERNDEF) {
00249 p -> sig_done = SIG_DONE;
00250 if (Gflag) {
00251 Gfind_inline(p);
00252 } else {
00253 find_inline(p);
00254 }
00255 return(SUCCESS);
00256 }
00257 may_fail = TRUE;
00258 r = findsig(p -> fc_body, is_void);
00259 may_fail = old_may_fail;
00260 if (r != SUCCESS) {
00261 dontsubst = cn_cons(p, dontsubst);
00262 p -> sig_done = SIG_DONE;
00263 return(SUCCESS);
00264 }
00265
00266 if (q == ERR_SIG
00267 || p -> fc_body -> signature == ERR_SIG) {
00268 p -> sig_done = SIG_DONE;
00269 return(SUCCESS);
00270 }
00271 if (q -> kind == VALSIGNATURE && !is_void
00272 && p -> fc_body -> signature -> kind
00273 != VALSIGNATURE) {
00274
00275 NODE * nresult;
00276
00277 nresult = coerce(p -> fc_body);
00278 if ((r = findsig(nresult,FALSE)) != SUCCESS) {
00279 p -> sig_done = SIG_UNKNOWN;
00280 vfree(nresult);
00281 return(r);
00282 }
00283 chgfld(&(p -> fc_body), nresult);
00284 }
00285 if (q -> kind == TYPESIGNATURE
00286 && amatch(p -> fc_body -> signature,q)
00287 && match_delv != NIL) {
00288 NODE * nresult = mknode(MODPRIMARY,
00289 p -> fc_body,
00290 NIL,
00291 match_delv
00292 );
00293
00294 nresult -> mp_orig_length = match_len;
00295 initfld(&(nresult -> signature), q);
00296 nresult -> sig_done = SIG_DONE;
00297 chgfld(&(p -> fc_body), nresult);
00298 }
00299
00300
00301 if (comp_st(p -> fc_body -> signature,
00302 p -> signature -> fsig_result_sig,
00303 NIL, NIL) == 0) {
00304 chgfld(&(p -> signature -> fsig_result_sig),
00305 p -> fc_body -> signature);
00306 }
00307 if (Gflag) {
00308 Gfind_inline(p);
00309 } else {
00310 find_inline(p);
00311 }
00312 p -> sig_done = SIG_DONE;
00313 return(SUCCESS);
00314 }
00315
00316 case APPLICATION:
00317 return(findapplsig(p));
00318
00319 case GUARDEDLIST:
00320 {
00321 NODE * good_element;
00322
00323 boolean kinds_differ;
00324
00325
00326 boolean coerce_guards;
00327 int prev_kind = -1;
00328 int curr_kind;
00329 boolean old_may_fail = may_fail;
00330
00331 good_element = NIL;
00332 all_ok = TRUE;
00333 kinds_differ = FALSE;
00334 coerce_guards = FALSE;
00335
00336 maplist(q, p -> gl_list, {
00337 IFDEBUG(
00338 if(q -> kind != GUARDEDELEMENT) {
00339 dbgmsg("findsig: Bad guarded element\n");
00340 }
00341 )
00342 if(findsig(q -> ge_element,dont_coerce) == SUCCESS) {
00343 good_element = q;
00344 if (q -> ge_element -> signature != ERR_SIG) {
00345 curr_kind = q -> ge_element -> signature
00346 -> kind;
00347 if (prev_kind != -1
00348 && curr_kind != prev_kind) {
00349 kinds_differ = TRUE;
00350 }
00351 prev_kind = curr_kind;
00352 }
00353 } else {
00354 all_ok = FALSE;
00355 }
00356 });
00357 may_fail = TRUE;
00358
00359 begin_maplist(s, p -> gl_list) {
00360 if((q = findsig(s -> ge_guard,FALSE)) != SUCCESS) {
00361 # ifdef TRACE
00362 printf("Couldn't find guard signature\n");
00363 # endif
00364 all_ok = FALSE;
00365 } else if (s -> ge_guard -> signature != ERR_SIG
00366 && s -> ge_guard -> signature -> kind
00367 != VALSIGNATURE) {
00368 # ifdef TRACE
00369 printf("Must coerce guards\n");
00370 # endif
00371 coerce_guards = TRUE;
00372 }
00373 } end_maplist;
00374 may_fail = old_may_fail;
00375 if (good_element == NIL || (may_fail && !all_ok)) {
00376
00377
00378 p -> sig_done = SIG_UNKNOWN;
00379 # ifdef TRACE
00380 printf("Giving up\n");
00381 # endif
00382 return(p);
00383 }
00384 if ( (kinds_differ || coerce_guards)
00385 ) {
00386
00387
00388 if ((!dont_coerce) && kinds_differ) {
00389
00390
00391 good_element = NIL;
00392 }
00393 begin_maplist(s, p -> gl_list) {
00394 if (!dont_coerce && kinds_differ
00395 && s -> ge_element -> signature != NIL) {
00396 NODE * nelement = coerce(s -> ge_element);
00397
00398 if (nelement -> sig_done == SIG_UNKNOWN) {
00399 if ((q = findsig(nelement, FALSE))
00400 == SUCCESS) {
00401 good_element = s;
00402 chgfld(&(s -> ge_element), nelement);
00403 } else {
00404 all_ok = FALSE;
00405 vfree(nelement);
00406 if (may_fail) {
00407 p -> sig_done = SIG_UNKNOWN;
00408 return(s);
00409 }
00410 }
00411 } else {
00412 good_element = s;
00413 }
00414 }
00415 if (coerce_guards
00416 && s -> ge_guard -> signature != NIL) {
00417 NODE * nguard = lock(coerce(s -> ge_guard));
00418
00419 # ifdef TRACE
00420 printf("Coercing guard\n");
00421 # endif
00422 if (nguard -> sig_done == SIG_UNKNOWN) {
00423 if ((q = findsig(nguard, FALSE))
00424 == SUCCESS) {
00425 # ifdef TRACE
00426 printf("Changed ");
00427 unparse_file = stdout;
00428 unparse(s -> ge_guard);
00429 printf(" to ");
00430 unparse(nguard);
00431 printf(" with signature ");
00432 unparse(nguard -> signature);
00433 printf("and refcount %d\n", nguard -> refcount);
00434 # endif
00435 chgfld(&(s -> ge_guard), nguard);
00436 unlock(nguard);
00437 } else {
00438 vfree(unlock(nguard));
00439 p -> sig_done = SIG_UNKNOWN;
00440 return(s);
00441 }
00442 }
00443 }
00444 }end_maplist;
00445 }
00446
00447
00448
00449
00450 # ifdef DEBUG
00451 if (good_element == NIL) {
00452 dbgmsg("findsig: bad good_element\n");
00453 }
00454 # endif
00455 if(!all_ok) {
00456
00457
00458 dontsubst = cn_cons(p, dontsubst);
00459 }
00460 initsig(p, good_element -> ge_element -> signature);
00461 if (!dont_coerce )
00462
00463 maplist(q, p -> gl_list, {
00464 r = fixhints(p -> signature,
00465 q -> ge_element -> signature);
00466 if (r != p -> signature) {
00467 chgsig(p, r);
00468 }
00469 });
00470 p -> sig_done = SIG_DONE;
00471 return(SUCCESS);
00472 }
00473
00474 case BLOCKDENOTATION:
00475 {
00476 NODE * last_den = last(p -> bld_den_seq);
00477 boolean old_may_fail = may_fail;
00478
00479 if((q = findsig(last_den,FALSE)) != SUCCESS) {
00480 p -> sig_done = SIG_UNKNOWN;
00481 return(q);
00482 }
00483 all_ok = TRUE;
00484 may_fail = TRUE;
00485
00486 maplist(s, p -> bld_declaration_list, {
00487 if((q = findsig(s -> decl_denotation,FALSE)) != SUCCESS) {
00488 all_ok = FALSE;
00489 }
00490 });
00491 maplist(s, p -> bld_den_seq, {
00492 if((q = findsig(s,TRUE)) != SUCCESS) {
00493 all_ok = FALSE;
00494 }
00495 });
00496 may_fail = old_may_fail;
00497 initsig(p, last_den -> signature);
00498 if (!Nflag || !(p -> bld_flags & NO_SURR_LOOP)) {
00499
00500 clear_slink_known(p -> signature);
00501 }
00502 if (!all_ok)
00503 dontsubst = cn_cons(p, dontsubst);
00504 p -> sig_done = SIG_DONE;
00505 return(SUCCESS);
00506 }
00507
00508 case USELIST:
00509 {
00510 NODE * last_den = last(p -> usl_den_seq);
00511 boolean old_may_fail = may_fail;
00512
00513
00514 maplist(s, p -> usl_type_list, {
00515 if((q = findsig(s,FALSE)) != SUCCESS) {
00516 p -> sig_done = SIG_UNKNOWN;
00517 return(q);
00518 } else {
00519 if (s -> signature != ERR_SIG
00520 && (s -> signature -> kind == LETTERID
00521 || s -> signature -> kind == OPRID)) {
00522 chgfld(&(s -> signature),
00523 sig_structure(s -> signature));
00524 }
00525 }
00526 });
00527 if((q = findsig(last_den,FALSE)) != SUCCESS) {
00528 p -> sig_done = SIG_UNKNOWN;
00529 return(q);
00530 }
00531
00532 may_fail = TRUE;
00533 all_ok = TRUE;
00534 maplist(s, p -> usl_den_seq, {
00535 if((q = findsig(s,TRUE)) != SUCCESS) {
00536 all_ok = FALSE;
00537 }
00538 });
00539 may_fail = old_may_fail;
00540 initsig(p, last_den -> signature);
00541 if (!all_ok)
00542 dontsubst = cn_cons(p, dontsubst);
00543 p -> sig_done = SIG_DONE;
00544 return(SUCCESS);
00545 }
00546
00547 case WORDELSE:
00548 initfld(&(p -> signature), val_Boolean);
00549 p -> sig_done = SIG_DONE;
00550 return(SUCCESS);
00551
00552 case LOOPDENOTATION:
00553 {
00554
00555 boolean old_may_fail = may_fail;
00556
00557 all_ok = TRUE;
00558 may_fail = TRUE;
00559 maplist(s, p -> gl_list, {
00560 if((q = findsig(s -> ge_guard,FALSE)) != SUCCESS) {
00561 all_ok = FALSE;
00562 } else {
00563
00564 NODE * nguard = coerce(s -> ge_guard);
00565
00566 if (nguard -> sig_done == SIG_UNKNOWN) {
00567 if ((q = findsig(nguard, FALSE))
00568 == SUCCESS) {
00569 chgfld(&(s -> ge_guard), nguard);
00570 } else {
00571 vfree(nguard);
00572 p -> sig_done = SIG_UNKNOWN;
00573 may_fail = old_may_fail;
00574 return(s);
00575 }
00576 }
00577 }
00578 if((q = findsig(s -> ge_element,TRUE)) != SUCCESS) {
00579 all_ok = FALSE;
00580 }
00581 });
00582 may_fail = old_may_fail;
00583 initfld(&(p -> signature), val_Void);
00584 if (!all_ok)
00585 dontsubst = cn_cons(p, dontsubst);
00586 p -> sig_done = SIG_DONE;
00587 return(SUCCESS);
00588 }
00589
00590 # ifdef DEBUG
00591 case WORDCAND:
00592 case WORDCOR:
00593 dbgmsg("findsig: cand or cor in syntax tree\n");
00594 return(SUCCESS);
00595 # endif
00596 case QSTR:
00597 case UQSTR:
00598 if ((q = findstdecl(p)) != SUCCESS) {
00599 p -> sig_done = SIG_UNKNOWN;
00600 return(q);
00601 }
00602 if (p -> sel_type == NIL) {
00603 switch(p -> kind) {
00604 case QSTR:
00605 errmsg1(p,
00606 "No appropriate type for \"%s\"",
00607 p -> str_string);
00608 break;
00609 case UQSTR:
00610 errmsg1(p,
00611 "No appropriate type for %s",
00612 p -> str_string);
00613 break;
00614 }
00615 p -> signature = ERR_SIG;
00616 p -> sig_done = SIG_DONE;
00617 return(SUCCESS);
00618 }
00619 if ((q = findsig(p -> sel_type, dont_coerce)) != SUCCESS) {
00620 p -> sig_done = SIG_UNKNOWN;
00621 return(q);
00622 }
00623 {
00624 NODE * sel_sig = p -> sel_type -> signature;
00625 NODE * r;
00626 int maxlen;
00627
00628
00629 if (sel_sig == ERR_SIG) {
00630 p -> signature = ERR_SIG;
00631 p -> sig_done = SIG_DONE;
00632 return(SUCCESS);
00633 }
00634 if (sel_sig -> ts_string_max == -1) {
00635 maxlen = MAXSTRLEN;
00636 } else {
00637 maxlen = sel_sig -> ts_string_max;
00638 }
00639 if (sel_sig -> ts_string_code != NIL
00640 && sel_sig -> ts_element_code != NIL
00641 && strlen(p -> str_string) <= maxlen
00642 && p -> sel_type -> kind == LETTERID
00643 && p -> sel_type -> sel_type == NIL) {
00644 if ((r = on_dontsubst(p -> sel_type)) != NIL) {
00645 p -> sig_done = SIG_UNKNOWN;
00646 return(r);
00647 }
00648
00649 initsig(p, mknode(VALSIGNATURE, p -> sel_type));
00650 p -> sig_done = SIG_DONE;
00651 return(SUCCESS);
00652 }
00653 }
00654 if (p -> str_expansion == NIL) {
00655 initfld(&(p->str_expansion), expand_str(p));
00656 }
00657 if ((q = findsig(p -> str_expansion, dont_coerce)) == SUCCESS) {
00658 initsig(p, p -> str_expansion -> signature);
00659 p -> sig_done = SIG_DONE;
00660 return(SUCCESS);
00661 } else {
00662 p -> sig_done = SIG_UNKNOWN;
00663 return(q);
00664 }
00665
00666 case MODPRIMARY:
00667 return(findmpsig(p));
00668
00669 case PRODCONSTRUCTION:
00670 {
00671 NODE * par_list = p -> prod_components;
00672 NODE * arg_list;
00673
00674 NODE * comp_list = lock(emptylist());
00675 NODE * local_id = p -> prod_local_type_id == NIL?
00676 mknode(LETTERID, UNDEFNAME)
00677 : copynode(p -> prod_local_type_id);
00678 NODE * self = mknode(VALSIGNATURE, local_id);
00679 boolean simple_type = TRUE;
00680 int len = length(par_list);
00681 int i;
00682
00683
00684 if (Gflag) {
00685 len = 0;
00686 maplist(s, par_list, {
00687 if (!vacuous_arg(s -> par_signature)) {
00688 len++;
00689 }
00690 });
00691 } else {
00692 len = length(par_list);
00693 }
00694
00695 r = mknode(TSCOMPONENT,
00696 mkcompnm(indx_New),
00697 copynode(sig_New));
00698 r -> tsc_signature -> fsig_special =
00699 special(PROD_NEW, len);
00700 init_inline(r);
00701 addright(comp_list, r);
00702 r = mknode(TSCOMPONENT,
00703 mkcompnm(indx_ValueOf),
00704 copynode(sig_ValueOf));
00705 r -> tsc_signature -> fsig_special =
00706 special(PROD_VALUEOF, len);
00707 init_inline(r);
00708 addright(comp_list, r);
00709 r = mknode(TSCOMPONENT,
00710 mkcompnm(indx_assign),
00711 copynode(sig_assign));
00712 r -> tsc_signature -> fsig_special =
00713 special(PROD_ASSIGN, len);
00714 init_inline(r);
00715 addright(comp_list, r);
00716
00717
00718 r = mknode(TSCOMPONENT,
00719 mkcompnm(indx_Mk),
00720 mknode(FUNCSIGNATURE, NIL,
00721 par_list,
00722 self
00723 )
00724 );
00725 r -> tsc_signature -> fsig_special =
00726 special(PROD_MK, len);
00727 init_inline(r);
00728 addright(comp_list, r);
00729
00730 {
00731 NODE * par = emptylist();
00732
00733 NODE * arg = emptylist();
00734
00735
00736 NODE * t;
00737
00738
00739 addright(par, t = mknode(PARAMETER, NIL, self));
00740 t -> pre_num = next_pre++;
00741
00742 addright(arg, t = mknode(LETTERID, UNDEFNAME));
00743 t -> id_last_definition = first(par);
00744 t -> id_def_found = TRUE;
00745
00746
00747 arg_list = lock(emptylist());
00748 maplist(s, par_list, {
00749 r = copynode(s -> par_id);
00750 chgfld(&(r -> sel_type), local_id);
00751 r -> id_last_definition = NIL;
00752 r -> id_def_found = TRUE;
00753 r = mknode(APPLICATION, r, arg);
00754 addright(arg_list,r);
00755 });
00756 i = 0;
00757 maplist(s, par_list, {
00758 boolean vac = Gflag && vacuous_arg(s -> par_signature);
00759
00760
00761 r = mknode(FUNCSIGNATURE,
00762 NIL ,
00763 par,
00764 subst(s -> par_signature,
00765 par_list,
00766 arg_list)
00767 );
00768 if (!vac) {
00769 r -> fsig_special = special(PROD_PROJ, i);
00770 } else {
00771 r -> fsig_special = special(UNDEF_CONST, 0);
00772 }
00773 IFDEBUG(
00774 if(substerr != NIL) {
00775 dbgmsg("findsig: unexpected substerr\n");
00776 }
00777 )
00778 if (s -> par_id == NIL) {
00779 errmsg0(s, "Product component not named");
00780 }
00781 r = mknode(TSCOMPONENT, s -> par_id, r);
00782 init_inline(r);
00783 addright(comp_list, r);
00784 if (!vac) {
00785 i++;
00786 }
00787 });
00788 }
00789 initsig(p, mknode(TYPESIGNATURE,
00790 local_id,
00791 comp_list,
00792 NIL, NIL, NIL));
00793 p -> signature -> pre_num = next_pre++;
00794
00795 tsig_order(p -> signature);
00796
00797
00798
00799 local_id -> id_def_found = TRUE;
00800 local_id -> id_last_definition = p -> signature;
00801 chgfld(&(p -> signature), tsubst(p -> signature,
00802 p,
00803 local_id,
00804 FALSE));
00805
00806 local_id -> id_def_found = TRUE;
00807 local_id -> id_last_definition = p -> signature;
00808 p -> sig_done = SIG_DONE;
00809
00810 maplist(s, par_list, {
00811 switch(s -> par_signature -> kind) {
00812 case FUNCSIGNATURE:
00813 case TYPESIGNATURE:
00814 simple_type = FALSE;
00815 break;
00816 case VALSIGNATURE:
00817 if(findsig(s -> par_signature
00818 -> val_denotation, FALSE)
00819 != SUCCESS) {
00820 simple_type = FALSE;
00821 } else {
00822 NODE * den_sig;
00823 den_sig = s -> par_signature
00824 -> val_denotation
00825 -> signature;
00826 if (den_sig != ERR_SIG
00827 && den_sig -> kind == TYPESIGNATURE) {
00828 simple_type = simple_type &&
00829 den_sig -> ts_simple_type;
00830 }
00831 }
00832
00833 }
00834 });
00835 p -> signature -> ts_simple_type = simple_type;
00836 unlock(comp_list);
00837 unlock(arg_list);
00838 vfree(arg_list);
00839 return(SUCCESS);
00840 }
00841
00842 case UNIONCONSTRUCTION:
00843 {
00844 NODE * field_list = p -> prod_components;
00845 NODE * comp_list = lock(emptylist());
00846 NODE * local_id = p -> prod_local_type_id == NIL?
00847 mknode(LETTERID, UNDEFNAME)
00848 : copynode(p -> prod_local_type_id);
00849 NODE * self = mknode(VALSIGNATURE, local_id);
00850 int len = length(field_list);
00851 int i;
00852 boolean simple_type;
00853
00854
00855 r = mknode(TSCOMPONENT,
00856 mkcompnm(indx_New),
00857 copynode(sig_New));
00858 r -> tsc_signature -> fsig_special =
00859 special(UNION_NEW, len);
00860 init_inline(r);
00861 addright(comp_list, r);
00862 r = mknode(TSCOMPONENT,
00863 mkcompnm(indx_ValueOf),
00864 copynode(sig_ValueOf));
00865 r -> tsc_signature -> fsig_special =
00866 special(UNION_VALUEOF, len);
00867 init_inline(r);
00868 addright(comp_list, r);
00869 r = mknode(TSCOMPONENT,
00870 mkcompnm(indx_assign),
00871 copynode(sig_assign));
00872 r -> tsc_signature -> fsig_special =
00873 special(UNION_ASSIGN, len);
00874 init_inline(r);
00875 addright(comp_list, r);
00876
00877 {
00878 NODE * par = emptylist();
00879
00880 NODE * t;
00881
00882
00883 addright(par, t = mknode(PARAMETER, NIL, self));
00884 t -> pre_num = next_pre++;
00885
00886 i = 0;
00887 begin_maplist(s, field_list) {
00888 boolean vac = Gflag && vacuous_arg(s -> par_signature);
00889
00890
00891 IFDEBUG(
00892 if (s -> kind != PARAMETER) {
00893 dbgmsg("findsig: bad union component\n");
00894 }
00895 )
00896 if (s -> par_id -> kind != LETTERID) {
00897 errmsg1(s, "Bad union field name: %s",
00898 getname(s -> par_id -> id_str_table_index));
00899 }
00900
00901 r = mknode(FUNCSIGNATURE,
00902 NIL ,
00903 par,
00904 s -> par_signature
00905 );
00906 if (!vac) {
00907 r -> fsig_special = special(UNION_PROJ, i);
00908 } else {
00909 r -> fsig_special = special(UNDEF_CONST, 0);
00910 }
00911 r -> fsig_inline_code =
00912 (*spcl_to_inline)(r -> fsig_special);
00913 addright(comp_list,
00914 mknode(TSCOMPONENT,
00915 prefix ("to_", s -> par_id),
00916 r)
00917 );
00918
00919 r = mknode(FUNCSIGNATURE,
00920 NIL ,
00921 par,
00922 val_Boolean
00923 );
00924 r -> fsig_special = special(UNION_INQ, i);
00925 r -> fsig_inline_code =
00926 (*spcl_to_inline)(r -> fsig_special);
00927 addright(comp_list,
00928 mknode(TSCOMPONENT,
00929 prefix ("is_", s -> par_id),
00930 r)
00931 );
00932
00933 r = mknode(FUNCSIGNATURE,
00934 NIL,
00935 mklist( mknode(PARAMETER,
00936 NIL,
00937 s -> par_signature),
00938 -1
00939 ),
00940 self
00941 );
00942 if (!vac) {
00943 r -> fsig_special = special(UNION_INJ, i);
00944 } else {
00945 r -> fsig_special = special(UNION_INJ0, i);
00946 }
00947 r -> fsig_inline_code =
00948 (*spcl_to_inline)(r -> fsig_special);
00949 addright(comp_list,
00950 mknode(TSCOMPONENT,
00951 prefix ("from_", s -> par_id),
00952 r)
00953 );
00954 i++;
00955 } end_maplist;
00956 }
00957 initsig(p, mknode(TYPESIGNATURE, NIL,
00958 comp_list,
00959 NIL, NIL, NIL));
00960 p -> signature -> pre_num = next_pre++;
00961
00962 tsig_order(p -> signature);
00963
00964
00965
00966 local_id -> id_def_found = TRUE;
00967 local_id -> id_last_definition = p -> signature;
00968 chgfld(&(p -> signature), tsubst(p -> signature,
00969 p,
00970 local_id,
00971 FALSE));
00972
00973 local_id -> id_last_definition = p -> signature;
00974 p -> sig_done = SIG_DONE;
00975
00976 maplist(s, field_list, {
00977 switch(s -> par_signature -> kind) {
00978 case FUNCSIGNATURE:
00979 case TYPESIGNATURE:
00980 simple_type = FALSE;
00981 break;
00982 case VALSIGNATURE:
00983 if(findsig(s -> par_signature
00984 -> val_denotation, FALSE)
00985 != SUCCESS) {
00986 simple_type = FALSE;
00987 } else {
00988 NODE * den_sig;
00989 den_sig = s -> par_signature
00990 -> val_denotation
00991 -> signature;
00992 if (den_sig != ERR_SIG
00993 && den_sig -> kind == TYPESIGNATURE) {
00994 simple_type = simple_type &&
00995 den_sig -> ts_simple_type;
00996 }
00997 }
00998
00999 }
01000 });
01001 p -> signature -> ts_simple_type = simple_type;
01002 vfree(comp_list);
01003 return(SUCCESS);
01004 }
01005
01006 case ENUMERATION:
01007 {
01008 NODE * id_list = p -> enum_id_list;
01009 NODE * comp_list = lock(emptylist());
01010 NODE * local_id = mknode(LETTERID, -1);
01011 NODE * self = mknode(VALSIGNATURE, local_id);
01012 NODE * self_param = mknode(PARAMETER, NIL, self);
01013 NODE * self_plist = mklist(self_param, -1);
01014 NODE * Int_param = mknode(PARAMETER, NIL, val_Integer);
01015 NODE * Int_plist = mklist(Int_param, -1);
01016 int len = length(id_list);
01017 int i;
01018
01019
01020 r = mknode(TSCOMPONENT,
01021 mkcompnm(indx_New),
01022 copynode(sig_New));
01023 r -> tsc_signature -> fsig_special =
01024 special(ENUM_NEW, len);
01025 init_inline(r);
01026 addright(comp_list, r);
01027 r = mknode(TSCOMPONENT,
01028 mkcompnm(indx_ValueOf),
01029 copynode(sig_ValueOf));
01030 r -> tsc_signature -> fsig_special =
01031 special(ENUM_VALUEOF, len);
01032 init_inline(r);
01033 addright(comp_list, r);
01034 r = mknode(TSCOMPONENT,
01035 mkcompnm(indx_assign),
01036 copynode(sig_assign));
01037 r -> tsc_signature -> fsig_special =
01038 special(ENUM_ASSIGN, len);
01039 init_inline(r);
01040 addright(comp_list, r);
01041 r = mknode(TSCOMPONENT,
01042 mkcompnm(indx_equals),
01043 copynode(sig_equals));
01044 r -> tsc_signature -> fsig_special =
01045 special(ENUM_EQ, len);
01046 init_inline(r);
01047 addright(comp_list, r);
01048 r = mknode(TSCOMPONENT,
01049 mkcompnm(indx_ne),
01050 copynode(sig_equals));
01051 r -> tsc_signature -> fsig_special =
01052 special(ENUM_NE, len);
01053 init_inline(r);
01054 addright(comp_list, r);
01055 r = mknode(TSCOMPONENT,
01056 mkcompnm(indx_First),
01057 copynode(sig_const));
01058 r -> tsc_signature -> fsig_special =
01059 special(ENUM_ELEMENT, 0);
01060 init_inline(r);
01061 addright(comp_list, r);
01062 r = mknode(TSCOMPONENT,
01063 mkcompnm(indx_Last),
01064 copynode(sig_const));
01065 r -> tsc_signature -> fsig_special =
01066 special(ENUM_ELEMENT, len-1);
01067 init_inline(r);
01068 addright(comp_list, r);
01069 r = mknode(TSCOMPONENT,
01070 mkcompnm(indx_Pred),
01071 mknode(FUNCSIGNATURE,
01072 NIL, self_plist, self));
01073 r -> tsc_signature -> fsig_special =
01074 special(ENUM_PRED, len);
01075 init_inline(r);
01076 addright(comp_list, r);
01077 r = mknode(TSCOMPONENT,
01078 mkcompnm(indx_Succ),
01079 mknode(FUNCSIGNATURE,
01080 NIL, self_plist, self));
01081 r -> tsc_signature -> fsig_special =
01082 special(ENUM_SUCC, len);
01083 init_inline(r);
01084 addright(comp_list, r);
01085 r = mknode(TSCOMPONENT,
01086 mkcompnm(indx_Ord),
01087 mknode(FUNCSIGNATURE,
01088 NIL, self_plist, val_Integer));
01089 r -> tsc_signature -> fsig_special =
01090 special(IDENTITY, len);
01091 init_inline(r);
01092 addright(comp_list, r);
01093 r = mknode(TSCOMPONENT,
01094 mkcompnm(indx_OrdInv),
01095 mknode(FUNCSIGNATURE,
01096 NIL, Int_plist, self));
01097 r -> tsc_signature -> fsig_special =
01098 special(IDENTITY, len);
01099 init_inline(r);
01100 addright(comp_list, r);
01101 r = mknode(TSCOMPONENT,
01102 mkcompnm(indx_Card),
01103 mknode(FUNCSIGNATURE,
01104 NIL, emptylist(), val_Integer));
01105 r -> tsc_signature -> fsig_special =
01106 special(ENUM_CARD, len);
01107 init_inline(r);
01108 addright(comp_list, r);
01109
01110 {
01111
01112 i = 0;
01113 maplist(s, id_list, {
01114 IFDEBUG(
01115 if (s -> kind != LETTERID && s -> kind != OPRID) {
01116 dbgmsg("findsig: bad enumeration element\n");
01117 }
01118 )
01119 r = copynode(sig_const);
01120 r -> fsig_special = special(ENUM_ELEMENT, i);
01121 r -> fsig_inline_code =
01122 (*spcl_to_inline)(r -> fsig_special);
01123 addright(comp_list,
01124 mknode(TSCOMPONENT, s, r)
01125 );
01126 i++;
01127 });
01128 }
01129 initsig(p, mknode(TYPESIGNATURE, NIL,
01130 comp_list,
01131 NIL, NIL, NIL));
01132 unlock(comp_list);
01133 p -> signature -> pre_num = next_pre++;
01134 p -> sig_done = SIG_DONE;
01135
01136 tsig_order(p -> signature);
01137 p -> signature -> ts_simple_type = TRUE;
01138 return(SUCCESS);
01139 }
01140
01141 case EXTENSION:
01142 {
01143 NODE * In_sig;
01144 NODE * Out_sig;
01145 NODE * sig;
01146 NODE * par_list;
01147 NODE * orig_sig;
01148 NODE * new_sig;
01149 NODE * local_id;
01150 NODE * id_In, * id_Out;
01151
01152 if ((q = findsig(p -> ext_denotation, FALSE)) != SUCCESS) {
01153 p -> sig_done = SIG_UNKNOWN;
01154 return(q);
01155 }
01156 if (p -> ext_denotation -> signature == ERR_SIG) {
01157 p -> signature = ERR_SIG;
01158 p -> sig_done = SIG_DONE;
01159 return(SUCCESS);
01160 }
01161
01162 sig = lock(copynode(p -> ext_denotation -> signature));
01163 if (sig -> kind != TYPESIGNATURE) {
01164 errmsg0(p -> ext_denotation,
01165 "Extension argument not a type");
01166 p -> signature = ERR_SIG;
01167 p -> sig_done = SIG_DONE;
01168 return(SUCCESS);
01169 }
01170 if (sig -> ts_local_type_id != NIL) {
01171 local_id = lock(copynode(sig -> ts_local_type_id));
01172 } else {
01173 local_id = mknode(LETTERID, UNDEFNAME);
01174 }
01175 sig -> pre_num = next_pre++;
01176
01177
01178 chgfld(&(sig -> ts_clist), copylist(sig -> ts_clist));
01179
01180 {
01181 NODE * Osig = sig;
01182
01183 local_id -> id_last_definition = sig;
01184 local_id -> id_def_found = TRUE;
01185 sig = lock(tsubst(sig,
01186 p -> ext_denotation -> signature,
01187 local_id,
01188 TRUE));
01189 local_id -> id_last_definition = sig;
01190 vfree(unlock(Osig));
01191 }
01192
01193 id_In = mknode(LETTERID, indx_In);
01194 id_Out = mknode(LETTERID, indx_Out);
01195
01196
01197 if (on_dontsubst(p -> ext_denotation) != NIL) {
01198 p -> sig_done = SIG_UNKNOWN;
01199 return(on_dontsubst(p -> ext_denotation));
01200 }
01201 orig_sig = mknode(VALSIGNATURE, p -> ext_denotation);
01202 new_sig = mknode(VALSIGNATURE, mknode(LETTERID, -1));
01203 par_list = mklist(mknode(PARAMETER, NIL, orig_sig), -1);
01204 In_sig = mknode(FUNCSIGNATURE,
01205 NIL,
01206 par_list,
01207 new_sig);
01208 par_list = mklist(mknode(PARAMETER, NIL, new_sig), -1);
01209 Out_sig = mknode(FUNCSIGNATURE,
01210 NIL,
01211 par_list,
01212 orig_sig);
01213 In_sig -> fsig_special = special(IDENTITY, 0);
01214 In_sig -> fsig_inline_code =
01215 (*spcl_to_inline)(In_sig -> fsig_special);
01216 Out_sig -> fsig_special = special(IDENTITY, 0);
01217 Out_sig -> fsig_inline_code =
01218 (*spcl_to_inline)(Out_sig -> fsig_special);
01219
01220
01221
01222 if (getcomp(sig, id_In, NIL, In_sig, sig, NIL, TRUE)
01223 != NIL) {
01224 errmsg0(p, "In occurs in extend argument sig");
01225 }
01226 if (getcomp(sig, id_Out, NIL, Out_sig, sig, NIL, TRUE)
01227 != NIL) {
01228 errmsg0(p, "Out occurs in extend argument sig");
01229 }
01230
01231 inscomp(sig, id_In, In_sig, NIL);
01232 p -> In_index = comp_index;
01233 inscomp(sig, id_Out, Out_sig, NIL);
01234 p -> Out_index = comp_index;
01235 initsig(p, sig);
01236 p -> sig_done = SIG_DONE;
01237
01238
01239 return(SUCCESS);
01240 }
01241
01242 case RECORDCONSTRUCTION:
01243 {
01244 NODE * field_list = p -> enum_id_list;
01245 NODE * comp_list = lock(emptylist());
01246 NODE * local_id = mknode(LETTERID, -1);
01247 NODE * self = mknode(VALSIGNATURE, local_id);
01248 NODE * self_param = mknode(PARAMETER, NIL, self);
01249 NODE * self_plist = mklist(self_param, -1);
01250 NODE * Mk_param_list = emptylist();
01251 NODE * id_New = mkcompnm(indx_New);
01252 NODE * id_ValueOf = mkcompnm(indx_ValueOf);
01253 NODE * id_assign = mkcompnm(indx_assign);
01254 NODE * re_den_sig;
01255 int len = length(field_list);
01256 int i;
01257
01258
01259
01260
01261 begin_maplist(s, p -> rec_component_list) {
01262 if ((q = findsig(s -> re_denotation, FALSE))
01263 != SUCCESS) {
01264 p -> sig_done = SIG_UNKNOWN;
01265 return(q);
01266 }
01267 re_den_sig = s -> re_denotation -> signature;
01268 if (re_den_sig == ERR_SIG) {
01269 err_return;
01270 }
01271 if (re_den_sig -> kind != TYPESIGNATURE) {
01272 errmsg0(s,
01273 "Non-type expression in record construction");
01274 err_return;
01275 }
01276 if (on_dontsubst(s -> re_denotation) != NIL) {
01277 p -> sig_done = SIG_UNKNOWN;
01278 return(on_dontsubst(s -> re_denotation));
01279 }
01280 if (getcomp(re_den_sig,
01281 id_ValueOf, NIL, sig_ValueOf, re_den_sig,
01282 NIL, TRUE) == NIL) {
01283 errmsg0(s, "No V operation in record component");
01284 }
01285 s -> re_ValueOf_index = comp_index;
01286 if (getcomp(re_den_sig,
01287 id_New, NIL, sig_New, re_den_sig,
01288 NIL, TRUE) == NIL) {
01289 errmsg0(s, "No New operation in record component");
01290 }
01291 s -> re_New_index = comp_index;
01292 if (getcomp(re_den_sig,
01293 id_assign, NIL, sig_assign, re_den_sig,
01294 NIL, TRUE) == NIL) {
01295 errmsg0(s, "No := operation in record component");
01296 }
01297 s -> re_assign_index = comp_index;
01298 } end_maplist;
01299
01300 r = mknode(TSCOMPONENT,
01301 id_New,
01302 copynode(sig_New));
01303 r -> tsc_signature -> fsig_special =
01304 special(RECORD_NEW, len);
01305 init_inline(r);
01306 addright(comp_list, r);
01307 r = mknode(TSCOMPONENT,
01308 id_ValueOf,
01309 copynode(sig_ValueOf));
01310 r -> tsc_signature -> fsig_special =
01311 special(RECORD_VALUEOF, len);
01312 init_inline(r);
01313 addright(comp_list, r);
01314 r = mknode(TSCOMPONENT,
01315 id_assign,
01316 copynode(sig_assign));
01317 r -> tsc_signature -> fsig_special =
01318 special(RECORD_ASSIGN, len);
01319 init_inline(r);
01320 addright(comp_list, r);
01321
01322 maplist(s, p -> rec_component_list, {
01323 r = mknode(VALSIGNATURE, s -> re_denotation);
01324 r = mknode(PARAMETER, NIL, r);
01325 addright(Mk_param_list, r);
01326 });
01327 r = mknode(FUNCSIGNATURE, NIL,
01328 Mk_param_list, self);
01329 r -> fsig_special = special(RECORD_MK, len);
01330 r = mknode(TSCOMPONENT,
01331 mkcompnm(indx_Mk),
01332 r);
01333 init_inline(r);
01334 addright(comp_list, r);
01335
01336 i = 0;
01337 begin_maplist(s, p -> rec_component_list) {
01338 NODE * vl_field_sig;
01339 NODE * vr_field_sig;
01340
01341 vl_field_sig =
01342 mknode(FUNCSIGNATURE,
01343 NIL,
01344 self_plist,
01345 mknode(VALSIGNATURE,
01346 s -> re_denotation));
01347 r = mklist(mknode(PARAMETER,
01348 NIL,
01349 mknode(VARSIGNATURE,local_id)),
01350 -1);
01351 vr_field_sig =
01352 mknode(FUNCSIGNATURE,
01353 NIL,
01354 r,
01355 mknode(VARSIGNATURE,
01356 s -> re_denotation));
01357 vl_field_sig -> fsig_special =
01358 special(RECORD_VAL_FIELD, i);
01359 vr_field_sig -> fsig_special =
01360 special(RECORD_VAR_FIELD, i);
01361 r = mknode(TSCOMPONENT,
01362 s -> re_id,
01363 vl_field_sig);
01364 init_inline(r);
01365 addright(comp_list, r);
01366 r = mknode(TSCOMPONENT,
01367 s -> re_id,
01368 vr_field_sig);
01369 init_inline(r);
01370 addright(comp_list, r);
01371 i++;
01372 } end_maplist;
01373 initsig(p, mknode(TYPESIGNATURE, NIL,
01374 comp_list,
01375 NIL, NIL, NIL));
01376 unlock(comp_list);
01377 p -> signature -> pre_num = next_pre++;
01378 p -> sig_done = SIG_DONE;
01379
01380 tsig_order(p -> signature);
01381
01382 p -> signature -> ts_simple_type = TRUE;
01383 maplist(s, p -> rec_component_list, {
01384 if (s -> re_denotation -> signature
01385 -> ts_simple_type == FALSE) {
01386 p -> signature -> ts_simple_type = FALSE;
01387 }
01388 });
01389 return(SUCCESS);
01390 }
01391
01392 case REXTERNDEF:
01393 dbgmsg("findsig: REXTERNDEF without signature\n");
01394 abort();
01395
01396 default:
01397 dbgmsg("findsig: unknown expression kind\n");
01398 abort();
01399 }
01400 # ifdef DEBUG
01401 findsig_out:
01402 # ifdef TRACE2
01403 printf("findsig: %X ", p);
01404 unparse_file = stdout;
01405 unparse(p);
01406 printf(" returning: %X\n", return_val);
01407 fflush(stdout);
01408 if (return_val != SUCCESS) {
01409 unparse(return_val);
01410 printf("\n");
01411 }
01412 # endif
01413 if (!is_ptr(return_val)) {
01414 dbgmsg("findsig returning bogus value: 0x%X\n", return_val);
01415 unparse_file = stdout;
01416 unparse(p);
01417 printf("\n");
01418 abort();
01419 }
01420 # undef return
01421 return(return_val);
01422 # endif
01423 }
01424
01425
01426
01427
01428
01429
01430
01431 NODE *
01432 declsig(p)
01433 NODE * p;
01434 {
01435 boolean old_may_fail;
01436 NODE * q;
01437 switch (p -> kind) {
01438 case DECLARATION:
01439 if (p -> decl_sig_done == SIG_DONE) {
01440 declerr = SUCCESS;
01441 return(p -> decl_signature);
01442 }
01443 old_may_fail = may_fail;
01444 may_fail = (may_fail || p -> decl_signature != NIL);
01445
01446
01447 declerr = findsig(p -> decl_denotation,FALSE);
01448 # ifdef TRACE
01449 printf("declsig: p = %X, declerr = %X\n", p, declerr);
01450 # endif
01451 if (declerr != SUCCESS) {
01452 if (p -> decl_signature != NIL) {
01453 declerr = SUCCESS;
01454 may_fail = old_may_fail;
01455 return(p -> decl_signature);
01456 }
01457
01458 if(declerr -> kind != LETTERID && declerr -> kind != OPRID) {
01459 declerr = p -> decl_id;
01460 # ifdef TRACE
01461 printf("Changing decl_err to %X\n", declerr);
01462 # endif
01463 }
01464 } else {
01465 p -> decl_sig_done = SIG_DONE;
01466 if (p -> decl_denotation -> signature == ERR_SIG) {
01467 p -> decl_signature = ERR_SIG;
01468 } else {
01469 chgfld(&(p -> decl_signature),
01470 p -> decl_denotation -> signature);
01471 }
01472 }
01473 may_fail = old_may_fail;
01474 return(p -> decl_signature);
01475 case PARAMETER:
01476 declerr = SUCCESS;
01477 return(p -> par_signature);
01478 case TYPESIGNATURE:
01479 declerr = SUCCESS;
01480 return(p);
01481 case PRODCONSTRUCTION:
01482 case RECORDCONSTRUCTION:
01483 case UNIONCONSTRUCTION:
01484 case MODPRIMARY:
01485 declerr = findsig(p,FALSE);
01486 return(p -> signature);
01487 # ifdef DEBUG
01488 default:
01489 dbgmsg("declsig: Bad declaration pointer: %x, kind=%s\n",
01490 p, kindname(p->kind));
01491 abort();
01492 # endif
01493 }
01494 }
01495
01496
01497
01498 void
01499 tl_findsig(p,dont_coerce)
01500 NODE *p;
01501 boolean dont_coerce;
01502 {
01503 NODE * q;
01504
01505
01506 switch (p -> kind) {
01507 case GUARDEDLIST:
01508 case LOOPDENOTATION:
01509 chgsig(p, NIL);
01510
01511 case FUNCCONSTR:
01512 p -> sig_done = SIG_UNKNOWN;
01513 }
01514 q = findsig(p,dont_coerce);
01515 if (q != SUCCESS) {
01516 if (q -> kind == LETTERID || q -> kind == OPRID) {
01517 errmsg1(q,"circular signature dependency involving %s",
01518 getname(q -> id_str_table_index));
01519 } else {
01520 errmsg0(q,"Circular signature dependency");
01521 }
01522 if (p -> kind == FUNCCONSTR) {
01523 p -> signature -> fsig_result_sig = ERR_SIG;
01524 } else {
01525 p -> signature = ERR_SIG;
01526 }
01527 p -> sig_done = SIG_DONE;
01528 }
01529
01530 while (dontsubst != NIL) {
01531 dontsubst = cn_del_hd(dontsubst);
01532 }
01533 }