00001 # define DEBUG
00002
00003 # define TRACE
00004 # undef TRACE
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 # include <stdio.h>
00026 # include <ctype.h>
00027 # include "parm.h"
00028
00029 # include "stree/ststructs.mh"
00030
00031 # include "../pass4/sigs.h"
00032
00033 # include "is_local.h"
00034
00035 char * getname();
00036
00037 extern FILE * unparse_file;
00038 extern int stplinks[];
00039 extern int yynerrs;
00040 extern char * entry_name;
00041
00042 static int fn_count = 0;
00043
00044 static boolean insig = FALSE;
00045
00046 static NODE * curr_void_decl = NIL;
00047
00048 static NODE * curr_sig_transp = NIL;
00049
00050
00051
00052
00053 static boolean in_loop = FALSE;
00054
00055 extern NODE * var_Void;
00056
00057 extern NODE * sig_Signature;
00058
00059 void check_sig();
00060
00061
00062
00063
00064 sigids(p)
00065 NODE * p;
00066 {
00067 register int * q;
00068
00069 register int v;
00070
00071
00072 boolean old_insig = insig;
00073 boolean old_in_loop = in_loop;
00074 NODE * old_void_decl = curr_void_decl;
00075 NODE * old_sig_transp = curr_sig_transp;
00076
00077 if (p == NIL) return;
00078 switch( p -> kind ) {
00079 case OPRID:
00080 case LETTERID:
00081 if ( p -> sel_type != NIL ) {
00082 p -> id_last_definition = NIL;
00083 p -> id_def_found = TRUE;
00084 sigids( p -> sel_type);
00085 } else if (insig) {
00086 # ifdef TRACE
00087 printf("Finding declaration of %s, curr_sig_transp = %X, def = %X\n",
00088 getname(p -> id_str_table_index), curr_sig_transp,
00089 p -> id_last_definition);
00090 # endif
00091 if (p -> signature != NIL && p -> sig_done != SIG_DONE) {
00092
00093 errmsg0(p,
00094 "Warning - signatures in signatures are ignored");
00095 yynerrs--;
00096 }
00097 if (curr_sig_transp != NIL
00098 && p -> id_last_definition != NIL) {
00099 NODE * def = p -> id_last_definition;
00100 NODE * imid = curr_sig_transp -> decl_innermost_id;
00101
00102
00103 if (def -> kind == DECLARATION) {
00104 NODE * id_def;
00105
00106
00107 if (def -> post_num >= p -> post_num) {
00108 errmsg1(p, "Forward reference to %s in === declaration",
00109 getname(p -> id_str_table_index));
00110 }
00111 if (def -> decl_sig_transp) {
00112 id_def = def -> decl_innermost_id;
00113 } else {
00114 id_def = def;
00115 }
00116 if (id_def != NIL &&
00117 (imid == NIL
00118 || is_descendant(id_def, imid -> decl_scope))) {
00119 curr_sig_transp -> decl_innermost_id = id_def;
00120 # ifdef TRACE
00121 unparse_file = stdout;
00122 printf("Setting innermost id of ");
00123 unparse(curr_sig_transp -> decl_id);
00124 printf(" to ");
00125 unparse(id_def -> decl_id);
00126 printf("\n");
00127 # endif
00128 # ifdef DEBUG
00129 if (id_def -> kind != DECLARATION) {
00130 dbgmsg("Sigids: Bad decl_innermost_id\n");
00131 }
00132 # endif
00133 }
00134 }
00135 }
00136
00137 if (p -> id_last_definition == NIL
00138 && p -> id_str_table_index != -1) {
00139
00140 NODE * usl = p -> id_use_list;
00141 NODE * sig, * def;
00142
00143 while (usl != NIL) {
00144 maplist(s, usl -> usl_type_list, {
00145 if ((s -> kind != LETTERID && s -> kind != OPRID)
00146 || s -> signature != NIL
00147 || s -> sel_type != NIL) {
00148 initfld(&(p -> sel_type), s);
00149 goto fixed_it;
00150 } else {
00151 def = s -> id_last_definition;
00152 if (def == NIL ||
00153 (def -> kind != DECLARATION &&
00154 def -> kind != PARAMETER) ||
00155 (def -> kind == DECLARATION &&
00156 def ->decl_signature == NIL)) {
00157 initfld(&(p -> sel_type),s);
00158 goto fixed_it;
00159 }
00160 sig = (def -> kind == PARAMETER) ?
00161 def -> par_signature :
00162 def -> decl_signature;
00163 if (sig -> kind == TYPESIGNATURE &&
00164 hascomp(sig, p -> id_str_table_index)) {
00165 initfld(&(p -> sel_type), s);
00166 goto fixed_it;
00167 }
00168 }
00169 });
00170 usl = usl -> usl_previous_list;
00171 }
00172 errmsg1(p,"%s undeclared",
00173 getname(p -> id_str_table_index));
00174
00175 p -> signature = ERR_SIG;
00176 p -> sig_done = SIG_DONE;
00177 break;
00178 }
00179 fixed_it:
00180 p -> id_def_found = TRUE;
00181 sigids(p -> sel_type);
00182 }
00183 check_sig(p -> signature);
00184 sigids( p -> signature );
00185 break;
00186
00187 case QSTR:
00188 case UQSTR:
00189 if ( p -> sel_type != NIL ) {
00190 sigids( p -> sel_type);
00191 initfld(&(p -> str_expansion), expand_str(p));
00192 } else if (insig) {
00193
00194 NODE * usl = p -> str_use_list;
00195 NODE * sig, * def;
00196
00197 while (usl != NIL) {
00198 maplist(s, usl -> usl_type_list, {
00199 if ((s -> kind != LETTERID && s -> kind != OPRID)
00200 || s -> signature != NIL
00201 || s -> sel_type != NIL) {
00202 initfld(&(p -> sel_type), s);
00203 goto str_fixed_it;
00204 } else {
00205 def = s -> id_last_definition;
00206 if (def == NIL ||
00207 (def -> kind != DECLARATION &&
00208 def -> kind != PARAMETER) ||
00209 (def -> kind == DECLARATION &&
00210 def ->decl_signature == NIL)) {
00211 initfld(&(p -> sel_type),s);
00212 goto str_fixed_it;
00213 }
00214 sig = (def -> kind == PARAMETER) ?
00215 def -> par_signature :
00216 def -> decl_signature;
00217 if (sig -> kind == TYPESIGNATURE &&
00218 hasstring(sig, p)) {
00219 initfld(&(p -> sel_type), s);
00220 goto str_fixed_it;
00221 }
00222 }
00223 });
00224 usl = usl -> usl_previous_list;
00225 }
00226
00227 switch(p -> kind) {
00228 case QSTR:
00229 errmsg1(p, "No appropriate type for \"%s\" inside signature",
00230 p -> str_string);
00231 break;
00232 case UQSTR:
00233 errmsg1(p, "No appropriate type for %s inside signature",
00234 p -> str_string);
00235 break;
00236 }
00237 p -> signature = ERR_SIG;
00238 p -> sig_done = SIG_DONE;
00239 break;
00240 str_fixed_it:
00241 initfld(&(p -> str_expansion), expand_str(p));
00242 }
00243 break;
00244
00245 case RECORDCONSTRUCTION:
00246 maplist(s, p -> rec_component_list, {
00247 sigids(s -> re_denotation);
00248 });
00249 break;
00250
00251 case FUNCCONSTR:
00252
00253 if (p -> fc_code_label == NIL) {
00254 # define FN_LN_LEN 16
00255 char * fn_name =
00256 (char *) malloc(strlen(entry_name)+FN_LN_LEN);
00257
00258 findvl(p -> vlineno);
00259 sprintf(fn_name,"fn_%s.ln%d_%d",entry_name,getrl(),fn_count++);
00260 p -> fc_code_label = fn_name;
00261 }
00262 in_loop = FALSE;
00263
00264 maplist(s, p -> signature -> fsig_param_list, {
00265 check_sig(s -> par_signature);
00266 if (comp_st(s -> par_signature,
00267 var_Void, NIL, NIL) == 0) {
00268 curr_void_decl = s;
00269 }
00270 });
00271 insig = TRUE;
00272 maplist(s, p -> signature -> fsig_param_list, {
00273 sigids(s -> par_signature);
00274 });
00275 check_sig(p -> signature -> fsig_result_sig);
00276 sigids(p -> signature -> fsig_result_sig);
00277 insig = old_insig;
00278 sigids(p -> fc_body);
00279 p -> signature -> fsig_slink_known = TRUE;
00280
00281
00282
00283 break;
00284
00285 case APPLICATION:
00286 sigids(p -> ap_operator);
00287 sigids(p -> ap_args);
00288 p -> ap_void_decl = curr_void_decl;
00289 break;
00290
00291 case BLOCKDENOTATION:
00292 if (!in_loop) {
00293 p -> bld_flags |= NO_SURR_LOOP;
00294 }
00295 sigids(p -> bld_declaration_list);
00296 sigids(p -> bld_den_seq);
00297 break;
00298
00299 case DECLARATION:
00300 if (p -> decl_denotation -> kind == FUNCCONSTR
00301 && p -> decl_id -> kind == LETTERID
00302 && p -> decl_denotation -> fc_code_label == NIL) {
00303
00304 # define FN_NAME_LEN 10
00305 char * id_name = getname(p -> decl_id -> id_str_table_index);
00306 if (id_name[0] != '\'') {
00307 char * fn_name =
00308 (char *) malloc(strlen(id_name)
00309 +strlen(entry_name)+FN_NAME_LEN);
00310 sprintf(fn_name,"fn_%s.%s_%d",entry_name,id_name,fn_count++);
00311 p -> decl_denotation -> fc_code_label = fn_name;
00312 }
00313 }
00314 insig = TRUE;
00315 check_sig(p -> decl_signature);
00316 sigids(p -> decl_signature);
00317 if (!p -> decl_sig_transp) {
00318 insig = old_insig;
00319 } else {
00320
00321 curr_sig_transp = p;
00322 }
00323 sigids(p -> decl_denotation);
00324 break;
00325
00326 case TSCOMPONENT:
00327 check_sig(p -> tsc_signature);
00328 sigids(p -> tsc_signature);
00329
00330 break;
00331
00332 case EXPORTELEMENT:
00333 sigids(p -> ee_export_list);
00334 insig = TRUE;
00335 check_sig(p -> ee_signature);
00336 sigids(p -> ee_signature);
00337 break;
00338
00339 case REXTERNDEF:
00340
00341 break;
00342
00343 case PARAMETER:
00344 insig = TRUE;
00345 check_sig(p -> par_signature);
00346 sigids(p -> par_signature);
00347
00348 break;
00349
00350 case LOOPDENOTATION:
00351 in_loop = TRUE;
00352 goto dflt;
00353
00354 case MODPRIMARY:
00355 p -> mp_no_surr_loop = !in_loop;
00356 goto dflt;
00357
00358 case TYPESIGNATURE:
00359 case FUNCSIGNATURE:
00360 case VALSIGNATURE:
00361 case VARSIGNATURE:
00362 insig = TRUE;
00363
00364
00365 default:
00366 dflt:
00367
00368 if (is_list(p)) {
00369 maplist(e, p, {
00370 sigids(e);
00371 });
00372 } else {
00373 v = stplinks[p -> kind];
00374 q = (int *) p;
00375 while ( v != 0 ) {
00376 if ( v < 0 ) {
00377 sigids(*q);
00378 }
00379 q++;
00380 v <<= 1;
00381 }
00382 }
00383 }
00384 insig = old_insig;
00385 curr_void_decl = old_void_decl;
00386 curr_sig_transp = old_sig_transp;
00387 }
00388
00389
00390
00391 void check_sig(q)
00392 NODE *q;
00393 {
00394 register NODE *p = q;
00395
00396 if (p == NIL) return;
00397 while ( (p -> kind == LETTERID || p -> kind == OPRID)
00398 && p -> sel_type == NIL
00399 && p -> id_last_definition != NIL
00400 && p -> id_last_definition -> kind == DECLARATION
00401 && p -> id_last_definition -> decl_sig_transp
00402 && p -> id_last_definition -> post_num < p -> post_num) {
00403 p = p -> id_last_definition -> decl_denotation;
00404 }
00405 switch (p -> kind) {
00406 case SIGNATURESIG:
00407 case VALSIGNATURE:
00408 case VARSIGNATURE:
00409 case FUNCSIGNATURE:
00410 case TYPESIGNATURE:
00411 break;
00412 default:
00413 if (p -> kind == LETTERID || p -> kind == OPRID) {
00414 if ( p -> id_last_definition == NIL
00415 || p -> id_last_definition -> kind != PARAMETER
00416 || comp_st(p -> id_last_definition -> par_signature,
00417 sig_Signature, NIL, NIL) != 0) {
00418 errmsg1(q,
00419 "Identifier %s not meaningfully bound to a signature",
00420 getname(q -> id_str_table_index));
00421 }
00422 } else {
00423 errmsg0(q, "Signature expected");
00424 }
00425 }
00426 }