00001 # define DEBUG
00002
00003 # ifdef DEBUG
00004 # define IFDEBUG(x) x
00005 # else
00006 # define IFDEBUG(x)
00007 # endif
00008
00009 # include <stdio.h>
00010 # include "parm.h"
00011
00012 # include "stree/ststructs.mh"
00013
00014 # include "sigs.h"
00015
00016 # include "stree/is_ptr.h"
00017
00018 NODE * curr_tsig = NIL;
00019
00020 boolean in_sig;
00021
00022 # define ERR_NODE_DEFINED
00023 NODE * err_node = NIL;
00024
00025 char * err_msg;
00026
00027 extern NODE * val_Boolean,
00028 * val_Void,
00029 * var_Void;
00030
00031 extern NODE * sig_Signature;
00032
00033 extern int yynerrs;
00034
00035 extern FILE * unparse_file;
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049 checksigs(p,dont_coerce)
00050 NODE * p;
00051 {
00052 register int knd;
00053 NODE * op;
00054
00055 if (p == ERR_SIG) return;
00056 knd = p -> kind;
00057
00058 switch(knd) {
00059 case OPRID:
00060 case LETTERID:
00061 if (p -> sel_type != NIL) {
00062
00063
00064 checksigs(p -> sel_type, FALSE);
00065 }
00066 tl_findsig(p,dont_coerce);
00067 if (p -> sel_type != NIL && in_sig
00068 && p -> sel_type -> signature != ERR_SIG) {
00069
00070 if (!is_unique(p -> sel_type -> signature,
00071 p -> id_str_table_index)) {
00072 errmsg0(p, "ambiguous selection in signature");
00073 }
00074 }
00075 break;
00076
00077 case QSTR:
00078 case UQSTR:
00079 {
00080 NODE * sig;
00081 int maxlen;
00082 tl_findsig(p, dont_coerce);
00083 if (p -> signature != ERR_SIG) {
00084 sig = p -> sel_type -> signature;
00085 if (sig -> ts_string_max == -1) {
00086 maxlen = MAXSTRLEN;
00087 } else {
00088 maxlen = sig -> ts_string_max;
00089 }
00090 if (sig -> ts_string_code == NIL
00091 || sig -> ts_element_code == NIL
00092 || strlen(p -> str_string) > maxlen
00093 || p -> sel_type -> kind != LETTERID
00094 || p -> sel_type -> sel_type != NIL) {
00095 checksigs(p -> str_expansion, dont_coerce);
00096 } else {
00097 checksigs(p -> sel_type, FALSE);
00098 }
00099 }
00100 }
00101 break;
00102
00103 case FUNCCONSTR:
00104 {
00105 boolean is_val_Void =
00106 (comp_st(val_Void,
00107 p -> signature -> fsig_result_sig,
00108 NIL, NIL) == 0);
00109 checksigs(p -> fc_body, is_val_Void);
00110 tl_findsig(p,dont_coerce);
00111 if (!in_sig &&
00112 p -> signature -> fsig_result_sig != ERR_SIG) {
00113
00114
00115
00116 in_sig = TRUE;
00117 if (p -> signature -> fsig_result_sig -> kind
00118 == VALSIGNATURE) {
00119 tl_findsig(p -> signature -> fsig_result_sig
00120 -> val_denotation, FALSE);
00121 }
00122 maplist(q, p -> signature -> fsig_param_list, {
00123 NODE * sig = q -> par_signature;
00124
00125 if (sig -> kind == VARSIGNATURE) {
00126 tl_findsig(sig -> var_denotation, FALSE);
00127 }
00128 });
00129 in_sig = FALSE;
00130 }
00131 if (p -> fc_body -> kind == EXTERNDEF) {
00132
00133 NODE * psig;
00134
00135 if (is_empty(p -> signature -> fsig_param_list)) {
00136 psig = NIL;
00137 } else {
00138 psig = last(p -> signature -> fsig_param_list) -> par_signature;
00139 }
00140 if (comp_st(psig, var_Void, NIL, NIL) != 0) {
00141 errmsg0(p, "Warning - last parameter of extern should be var Void");
00142 yynerrs --;
00143 }
00144 } else {
00145
00146 if (!is_val_Void &&
00147 !amatch(p -> fc_body -> signature,
00148 p -> signature -> fsig_result_sig)) {
00149 errmsg0(p, "Function result signature mismatch");
00150 }
00151 }
00152 break;
00153 }
00154
00155 case REXTERNDEF:
00156 break;
00157
00158 case APPLICATION:
00159
00160 tl_findsig(p, dont_coerce);
00161 maplist(q, p -> ap_args, {
00162 checksigs(q,FALSE);
00163 });
00164 op = p -> ap_operator;
00165 if (op -> kind == OPRID || op -> kind == LETTERID) {
00166
00167 op -> id_appl = p;
00168 }
00169 checksigs(op, FALSE);
00170 tl_findsig(p,dont_coerce);
00171 if (p -> signature != ERR_SIG
00172 && op -> signature != ERR_SIG ) {
00173 NODE * op_sig = op -> signature;
00174 NODE * new_args;
00175 int num_args;
00176 int num_params;
00177
00178
00179
00180
00181
00182
00183
00184
00185 if (!in_sig) {
00186
00187 if (op -> signature -> fsig_inline_code == NIL
00188 && op -> signature -> fsig_construction != NIL) {
00189 op -> signature -> fsig_inline_code =
00190 op -> signature -> fsig_construction
00191 -> signature -> fsig_inline_code;
00192 }
00193
00194 in_sig = TRUE;
00195 err_node = p;
00196 err_msg = "signature of result type is bad";
00197 switch(p -> signature -> kind) {
00198 case VALSIGNATURE:
00199 tl_findsig(p -> signature -> val_denotation, TRUE);
00200 case VARSIGNATURE:
00201 tl_findsig(p -> signature -> var_denotation, TRUE);
00202 }
00203 in_sig = FALSE;
00204 err_node = NIL;
00205 }
00206
00207
00208
00209
00210 # ifdef DEBUG
00211 if (!is_ptr(op_sig)) {
00212 dbgmsg("checksigs: bad operator signature\n");
00213 unparse_file = stdout;
00214 unparse(p);
00215 printf("\n");
00216 prtree(p);
00217 printf("Signature:\n");
00218 prtree(p -> signature);
00219 abort();
00220 }
00221 if (!is_ptr(op_sig -> fsig_param_list)
00222 || !is_list(op_sig -> fsig_param_list)) {
00223 dbgmsg("checksigs: bad parameter list\n");
00224 abort();
00225 }
00226 if (!is_ptr(p -> ap_args) || !is_list(p -> ap_args)) {
00227 dbgmsg("checksigs: bad argument list\n");
00228 abort();
00229 }
00230 # endif
00231 num_args = length(p -> ap_args);
00232 num_params = length(op_sig -> fsig_param_list);
00233 if (num_args != num_params) {
00234 errmsg0(p, "wrong number of arguments");
00235 } else {
00236 NODE * par_sig;
00237
00238 begin_map2lists (s, p -> ap_args,
00239 r, op_sig -> fsig_param_list) {
00240 NODE * sig = s -> signature;
00241 NODE * den;
00242
00243 if (has_sig(s) &&
00244 (sig -> kind == VARSIGNATURE)
00245 && !in_sig) {
00246
00247 in_sig = TRUE;
00248 err_node = s;
00249 err_msg = "bad argument type signature";
00250 if (sig -> kind == VALSIGNATURE) {
00251 den = sig -> val_denotation;
00252 } else {
00253 den = sig -> var_denotation;
00254 }
00255 tl_findsig(den, TRUE);
00256 err_node = NIL;
00257 in_sig = FALSE;
00258 }
00259 par_sig = subst(r -> par_signature,
00260 op_sig -> fsig_param_list,
00261 p -> ap_args);
00262 lock(par_sig);
00263 if (!amatch(s -> signature, par_sig)) {
00264 extern NODE * failed_comp;
00265
00266 errmsg0(p, "Argument parameter mismatch");
00267 unparse_file = stderr;
00268 fprintf(stderr, "\tArgument:\n\t");
00269 unparse(s);
00270 fprintf(stderr,
00271 "\n\tParameter signature after substitution:\n\t");
00272 unparse(par_sig);
00273 if (failed_comp != NIL) {
00274 if (failed_comp -> kind == DEFCHARSIGS) {
00275 fprintf(stderr, "\n\tMissing Constant");
00276 } else {
00277
00278 fprintf(stderr,
00279 "\n\tOffending parameter component: ");
00280 unparse(failed_comp -> tsc_id);
00281 fprintf(stderr, ":");
00282 unparse(failed_comp -> tsc_signature);
00283 }
00284 }
00285 fprintf(stderr,
00286 "\n\tArgument signature:\n\t");
00287 unparse(s -> signature);
00288 fprintf(stderr, "\n");
00289 }
00290 vfree(unlock(par_sig));
00291 } end_map2lists;
00292 }
00293 }
00294 break;
00295
00296 case GUARDEDLIST:
00297 case LOOPDENOTATION:
00298 maplist(q, p -> gl_list, {
00299 checksigs(q -> ge_guard, FALSE);
00300 checksigs(q -> ge_element, knd==LOOPDENOTATION || dont_coerce);
00301 });
00302 tl_findsig(p,dont_coerce);
00303
00304 maplist(q, p -> gl_list, {
00305 if (q -> ge_guard -> signature != ERR_SIG &&
00306 comp_st(q -> ge_guard -> signature,
00307 val_Boolean, NIL,NIL) != 0) {
00308 errmsg0(q -> ge_guard, "Guard has inappropriate signature");
00309 unparse_file = stderr;
00310 fprintf(stderr, "\tGuard signature:\n\t");
00311 unparse(q -> ge_guard -> signature);
00312 fprintf(stderr, "\n");
00313 }
00314 });
00315 if(!dont_coerce && knd == GUARDEDLIST
00316 && p -> signature != ERR_SIG) {
00317
00318 maplist(q, p -> gl_list, {
00319 if (q -> ge_element -> signature != ERR_SIG
00320 && comp_st(q -> ge_element -> signature,
00321 p -> signature, NIL, NIL) != 0) {
00322 errmsg0(q -> ge_element,
00323 "Guarded expression has incorrect signature:");
00324 unparse_file = stderr;
00325 fprintf(stderr, "\t");
00326 unparse(q -> ge_element -> signature);
00327 fprintf(stderr, "\n\tShould be:\n\t");
00328 unparse(p -> signature);
00329 fprintf(stderr, "\n");
00330 }
00331 });
00332 }
00333 break;
00334
00335 case BLOCKDENOTATION:
00336 maplist(q, p -> bld_declaration_list, {
00337 checksigs(q -> decl_denotation,FALSE);
00338 if (q -> decl_signature != NIL &&
00339 q -> decl_denotation -> signature != ERR_SIG &&
00340 comp_st(q -> decl_signature,
00341 q -> decl_denotation -> signature, NIL, NIL) != 0) {
00342 errmsg0(q, "Signature does not match declaration");
00343 unparse_file = stderr;
00344 fprintf(stderr, "\texplicit signature:\n\t");
00345 unparse(q -> decl_signature);
00346 fprintf(stderr, "\n\texpression signature:\n\t");
00347 unparse(q -> decl_denotation -> signature);
00348 fprintf(stderr, "\n");
00349 }
00350 if (q -> decl_signature == NIL) {
00351 q -> decl_signature = q -> decl_denotation -> signature;
00352 q -> decl_sig_done = SIG_DONE;
00353 }
00354 });
00355 maplist(q, p -> bld_den_seq, {
00356 if (q == last(p -> bld_den_seq)) {
00357 checksigs(q,dont_coerce);
00358 } else {
00359 checksigs(q,TRUE);
00360 }
00361 });
00362 tl_findsig(p,dont_coerce);
00363 break;
00364
00365 case USELIST:
00366 maplist(q, p -> usl_type_list, {
00367 checksigs(q,FALSE);
00368 if (q -> signature != ERR_SIG) {
00369 if (q -> signature -> kind != TYPESIGNATURE) {
00370 chgfld(&(q -> signature),
00371 sig_structure(q -> signature));
00372 if (q -> signature -> kind != TYPESIGNATURE) {
00373 errmsg0(q, "Non-type appears in use type list");
00374 }
00375 }
00376 }
00377 });
00378 maplist(q, p -> usl_den_seq, {
00379 if (q == last(p -> usl_den_seq)) {
00380 checksigs(q,dont_coerce);
00381 } else {
00382 checksigs(q,TRUE);
00383 }
00384 });
00385 tl_findsig(p,dont_coerce);
00386 break;
00387
00388 case WORDELSE:
00389 tl_findsig(p,dont_coerce);
00390 break;
00391
00392 case MODPRIMARY:
00393 checksigs(p -> mp_primary, FALSE);
00394
00395
00396
00397 {
00398 NODE * q;
00399
00400 if((q = findsig(p, dont_coerce)) != SUCCESS) {
00401 errmsg0(p, "Can't find signature of with list");
00402 fprintf(stderr,"\tOffending expression:\n\t");
00403 unparse_file = stderr;
00404 unparse(q);
00405 fprintf(stderr, "\n");
00406 p -> sig_done = SIG_DONE;
00407 p -> signature = ERR_SIG;
00408 break;
00409 };
00410 }
00411 if (!in_sig && has_sig(p -> mp_primary)) {
00412
00413 err_node = p;
00414 err_msg =
00415 "bad type signature before modification";
00416 checksigs(p -> mp_primary -> signature, FALSE);
00417 err_node = NIL;
00418 }
00419 if (p -> mp_type_modifier != NIL
00420 && p -> mp_type_modifier -> kind == WITHLIST) {
00421 maplist(q, p -> mp_type_modifier -> wl_component_list, {
00422 IFDEBUG(
00423 if (q -> kind != DECLARATION) {
00424 dbgmsg("checksigs: bad with list\n");
00425 }
00426 )
00427 checksigs(q -> decl_denotation, dont_coerce);
00428 if (q -> decl_signature != NIL &&
00429 q -> decl_denotation -> signature != ERR_SIG &&
00430 comp_st(q -> decl_signature,
00431 q -> decl_denotation -> signature,
00432 NIL, NIL) != 0) {
00433 errmsg0(q, "Signature does not match WITH declaration");
00434 }
00435 });
00436 tl_findsig(p, dont_coerce);
00437 if (!in_sig && has_sig(p)) {
00438
00439
00440 NODE * sig_after_hiding =
00441 lock(delcomp(p -> mp_primary -> signature,
00442 p -> mp_delete_v));
00443
00444 err_node = p;
00445 err_msg = "bad signature after hiding";
00446 checksigs(sig_after_hiding, FALSE);
00447 vfree(unlock(sig_after_hiding));
00448
00449
00450 err_msg = "bad signature after adding components";
00451 checksigs(p -> signature, FALSE);
00452 err_node = NIL;
00453 }
00454 } else {
00455 tl_findsig(p, dont_coerce);
00456
00457 if (!in_sig && has_sig(p)) {
00458 err_node = p;
00459 err_msg = "bad signature after hiding";
00460 checksigs(p -> signature, FALSE);
00461 err_node = NIL;
00462 }
00463 }
00464 break;
00465
00466 case RECORDCONSTRUCTION:
00467 tl_findsig(p,dont_coerce);
00468 maplist(q, p -> rec_component_list, {
00469 tl_findsig(q -> re_denotation);
00470 if (q -> re_denotation -> signature != ERR_SIG
00471 && q -> re_denotation -> signature -> kind
00472 != TYPESIGNATURE) {
00473 errmsg0(q, "Non-type expression in record");
00474 }
00475 });
00476 break;
00477
00478 case UNIONCONSTRUCTION:
00479 case PRODCONSTRUCTION:
00480 tl_findsig(p, dont_coerce);
00481 maplist(q, p -> prod_components, {
00482 if (q -> par_signature -> kind == VARSIGNATURE) {
00483 switch(p -> kind) {
00484 case PRODCONSTRUCTION:
00485 errmsg0(q, "Product shouldn't have var component");
00486 case UNIONCONSTRUCTION:
00487 errmsg0(q, "Union shouldn't have var component");
00488 }
00489 }
00490 });
00491 break;
00492
00493 case ENUMERATION:
00494 tl_findsig(p, dont_coerce);
00495 break;
00496
00497 case EXTENSION:
00498 checksigs(p -> ext_denotation);
00499 tl_findsig(p, dont_coerce);
00500 break;
00501
00502 case TYPESIGNATURE:
00503 {
00504 boolean old_in_sig = in_sig;
00505 NODE * old_curr_tsig = curr_tsig;
00506
00507 if (p -> signature == NIL) {
00508 initfld(&(p -> signature), sig_Signature);
00509 }
00510 p -> sig_done = SIG_DONE;
00511 in_sig = TRUE;
00512 curr_tsig = p;
00513
00514 maplist(s, p -> ts_clist, {
00515 if (s -> kind == TSCOMPONENT) {
00516 checksigs(s -> tsc_signature, FALSE);
00517 }
00518 });
00519 in_sig = old_in_sig;
00520 curr_tsig = old_curr_tsig;
00521 break;
00522 }
00523
00524 case FUNCSIGNATURE:
00525
00526
00527 if (p -> signature == NIL) {
00528 initfld(&(p -> signature), sig_Signature);
00529 }
00530 p -> sig_done = SIG_DONE;
00531 maplist(s, p -> fsig_param_list, {
00532 IFDEBUG(
00533 if (s -> kind != PARAMETER || !is_ptr(s -> par_signature)) {
00534 dbgmsg("checksigs: bad parameter\n");
00535 prtree(s);
00536 abort();
00537 }
00538 )
00539 checksigs(s -> par_signature, FALSE);
00540 });
00541 checksigs(p -> fsig_result_sig);
00542 break;
00543
00544 case VALSIGNATURE:
00545 if (p -> signature == NIL) {
00546 initfld(&(p -> signature), sig_Signature);
00547 }
00548 p -> sig_done = SIG_DONE;
00549 checksigs(p -> val_denotation, FALSE);
00550 break;
00551
00552 case VARSIGNATURE:
00553 if (p -> signature == NIL) {
00554 initfld(&(p -> signature), sig_Signature);
00555 }
00556 p -> sig_done = SIG_DONE;
00557 checksigs(p -> var_denotation, FALSE);
00558 break;
00559
00560 case SIGNATURESIG:
00561 if (p -> signature == NIL) {
00562 initfld(&(p -> signature), sig_Signature);
00563 }
00564 p -> sig_done = SIG_DONE;
00565 break;
00566
00567 case EXTERNDEF:
00568 break;
00569
00570 default:
00571 dbgmsg("checksigs: bad kind: %s\n",kindname(p -> kind));
00572 abort();
00573 }
00574 # ifdef DEBUG
00575 if (p -> kind != TYPESIGNATURE && p -> kind != FUNCSIGNATURE
00576 && p -> kind != VALSIGNATURE && p -> kind != VARSIGNATURE
00577 && p -> kind != EXTERNDEF && p -> sig_done == SIG_IN_PROGRESS) {
00578 dbgmsg("Checksigs: findsig blew it on %s\n", kindname(p -> kind));
00579 }
00580 # endif
00581 }
00582
00583
00584
00585
00586
00587
00588
00589 tl_checksigs(p)
00590 NODE * p;
00591 {
00592 checksigs(p, FALSE);
00593 import(p, NIL);
00594 }
00595