00001 # define TRACE_DECL
00002 # undef TRACE_DECL
00003
00004
00005
00006 # ifdef TRACE_DECL
00007 # define IFTRACE_DECL(x) x
00008 # else
00009 # define IFTRACE_DECL(x)
00010 # endif
00011
00012 # define EXTERN_LIMIT 5
00013
00014
00015
00016 # include "parm.h"
00017 # include <stdio.h>
00018 # include "stree/ststructs.mh"
00019 # include "pass3/is_local.h"
00020
00021 extern boolean Gflag;
00022
00023 extern FILE * unparse_file;
00024
00025 static NODE * Outer_arg;
00026
00027 struct decl_entry {
00028 NODE * de_decl;
00029 int de_number;
00030 struct decl_entry * de_next;
00031 } *decl_nums;
00032
00033
00034
00035 static int decl_num = 0;
00036
00037
00038 # define add_decl(decl) { \
00039 struct decl_entry * o = (struct decl_entry *) \
00040 malloc(sizeof (struct decl_entry)); \
00041 o -> de_number = (++decl_num); \
00042 o -> de_decl = decl; \
00043 o -> de_next = decl_nums; \
00044 decl_nums = o; \
00045 }
00046
00047 # define NONE -1
00048
00049
00050 static get_decl_num(decl)
00051 NODE * decl;
00052 {
00053 struct decl_entry *p = decl_nums;
00054
00055 while (p != NIL ) {
00056 if (decl -> pre_num == p -> de_decl -> pre_num) return(p -> de_number);
00057 p = p -> de_next;
00058 }
00059 return(NONE);
00060 }
00061
00062 void sig_out1();
00063
00064
00065
00066
00067
00068 put_string(Soutfile, s)
00069 FILE * Soutfile;
00070 char * s;
00071 {
00072 if (s == NIL) {
00073 putc(0xff, Soutfile);
00074 } else {
00075 fputs(s, Soutfile);
00076 }
00077 putc(0, Soutfile);
00078 }
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090 # define LOCALREP 0
00091 # define GLOBALREP 1
00092 # define SELECTREP 2
00093
00094
00095 put_name(Soutfile, p)
00096 register NODE *p;
00097 FILE *Soutfile;
00098 {
00099 int string_index;
00100 char * name;
00101 int rep;
00102 int dn;
00103
00104 # ifdef DEBUG
00105 if(p -> kind != LETTERID && p -> kind != OPRID) {
00106 dbgmsg("put_name: bad identifier\n");
00107 }
00108 # endif
00109 putw(p -> kind, Soutfile);
00110 if (p -> sel_type != NIL) {
00111 rep = SELECTREP;
00112 } else {
00113 if (p -> id_last_definition != NIL
00114 && (dn = get_decl_num(p -> id_last_definition)) != NONE) {
00115 rep = LOCALREP;
00116 } else {
00117 rep = GLOBALREP;
00118 }
00119 }
00120 putw(rep, Soutfile);
00121 # ifdef TRACE_DECL
00122 printf("put_name: identifier: %s; index: %d",
00123 (p -> id_str_table_index == -1? "(anon)"
00124 : getname(p -> id_str_table_index)),
00125 p -> id_str_table_index);
00126 # endif
00127 switch(rep) {
00128 case SELECTREP:
00129 sig_out1(Soutfile, p -> sel_type);
00130 # ifdef TRACE_DECL
00131 printf(" (selected)\n");
00132 # endif
00133 break;
00134 case GLOBALREP:
00135 putw(p -> id_last_definition, Soutfile);
00136 # ifdef TRACE_DECL
00137 printf(" (global)\n");
00138 # endif
00139 break;
00140 case LOCALREP:
00141 putw(dn, Soutfile);
00142 # ifdef TRACE_DECL
00143 printf(" (declaration: %d; pre_num: %d)\n", dn,
00144 p -> id_last_definition -> pre_num);
00145 # endif
00146 break;
00147 }
00148 string_index = p -> id_str_table_index;
00149 # ifdef DEBUG
00150 if (string_index <= -2) {
00151 dbgmsg("put_name: funny id name: %X\n", string_index);
00152 }
00153 # endif
00154 if (string_index == -1) {
00155
00156 putc(0, Soutfile);
00157 } else {
00158 put_string(Soutfile, getname(string_index));
00159 }
00160 }
00161
00162
00163
00164
00165
00166
00167 void sig_out(Soutfile, p)
00168 register NODE * p;
00169 FILE * Soutfile;
00170 {
00171 decl_nums = NIL;
00172 Outer_arg = p;
00173 sig_out1(Soutfile, p);
00174 }
00175
00176 void sig_out1(Soutfile, p)
00177 register NODE * p;
00178 FILE * Soutfile;
00179 {
00180 register NODE * v;
00181
00182 if (p == NIL) {
00183 putw(-1, Soutfile);
00184 return;
00185 }
00186
00187 switch ( p -> kind ) {
00188
00189 case DECLARATION:
00190 putw(DECLARATION, Soutfile);
00191
00192 put_name(Soutfile, p -> decl_id);
00193 putw(p -> decl_sig_transp, Soutfile);
00194 sig_out1(Soutfile, p -> decl_signature);
00195 sig_out1(Soutfile, p -> decl_denotation);
00196 break;
00197
00198 case BLOCKDENOTATION:
00199 putw(BLOCKDENOTATION, Soutfile);
00200 maplist(v, p -> bld_declaration_list, {
00201 add_decl(v);
00202 IFTRACE_DECL(
00203 printf("Declaration: %s, decl: %d\n",
00204 getname(v -> decl_id -> id_str_table_index),
00205 decl_num);
00206 )
00207 });
00208 putw(length(p -> bld_declaration_list), Soutfile);
00209 maplist(v, p -> bld_declaration_list, {
00210 sig_out1(Soutfile, v);
00211 });
00212 putw(length(p -> bld_den_seq), Soutfile);
00213 maplist(v, p -> bld_den_seq, {
00214 sig_out1(Soutfile, v);
00215 });
00216 break;
00217
00218 case APPLICATION:
00219 putw(APPLICATION, Soutfile);
00220 sig_out1(Soutfile, p -> ap_operator);
00221 putw(length(p -> ap_args), Soutfile);
00222 maplist(v, p -> ap_args, {
00223 sig_out1(Soutfile, v);
00224 });
00225 break;
00226
00227 case LOOPDENOTATION:
00228 case GUARDEDLIST:
00229 putw(p -> kind, Soutfile);
00230 putw(length(p -> gl_list), Soutfile);
00231 maplist(v, p -> gl_list, {
00232 sig_out1(Soutfile, v);
00233 });
00234 break;
00235
00236 case GUARDEDELEMENT:
00237 putw(GUARDEDELEMENT, Soutfile);
00238 sig_out1(Soutfile, p->ge_guard);
00239 sig_out1(Soutfile, p->ge_element);
00240 break;
00241
00242 case OPRID:
00243 case LETTERID:
00244 # ifdef DEBUG
00245 if (!p -> id_def_found) {
00246 dbgmsg("Sig_out: unresolved identifier reference\n");
00247 abort(p);
00248 }
00249 # endif
00250 if (p -> sel_type == NIL
00251 && p -> id_last_definition != NIL
00252 && p -> id_last_definition -> kind == DECLARATION
00253 && p -> id_last_definition -> decl_sig_transp) {
00254 # ifdef TRACE_DECL
00255 printf("Writing out ");
00256 unparse_file = stdout;
00257 unparse(p -> id_last_definition -> decl_denotation);
00258 printf("instead of identifier ");
00259 unparse(p);
00260 printf("\n");
00261 # endif
00262 sig_out1(Soutfile,
00263 p -> id_last_definition -> decl_denotation);
00264 } else {
00265 put_name(Soutfile, p);
00266 }
00267 break;
00268
00269 case FUNCCONSTR:
00270 putw(FUNCCONSTR, Soutfile);
00271 sig_out1(Soutfile, p -> signature);
00272 sig_out1(Soutfile, p -> fc_body);
00273 break;
00274
00275 case USELIST:
00276 putw(USELIST, Soutfile);
00277 putw(length(p -> usl_type_list), Soutfile);
00278 maplist(q, p -> usl_type_list, {
00279 sig_out1(Soutfile, q);
00280 });
00281 putw(length(p -> usl_den_seq), Soutfile);
00282 maplist(q, p -> usl_den_seq, {
00283 sig_out1(Soutfile, q);
00284 });
00285 break;
00286
00287 case MODPRIMARY:
00288 if (p -> mp_type_modifier == NIL) {
00289
00290 sig_out1(Soutfile, p -> mp_primary);
00291 } else {
00292 add_decl(p);
00293 # ifdef TRACE_DECL
00294 printf("Modified type: decl: %d\n",
00295 decl_num);
00296 # endif
00297 putw(MODPRIMARY, Soutfile);
00298 sig_out1(Soutfile, p -> mp_primary);
00299 sig_out1(Soutfile, p -> mp_type_modifier);
00300 }
00301 break;
00302
00303 case QSTR:
00304 case UQSTR:
00305 if (p -> str_expansion == NIL) {
00306 sig_out1(Soutfile, expand_str(p));
00307 } else {
00308 sig_out1(Soutfile, p -> str_expansion);
00309 }
00310 break;
00311
00312 case PRODCONSTRUCTION:
00313 case UNIONCONSTRUCTION:
00314 add_decl(p);
00315 # ifdef TRACE_DECL
00316 printf("Type construction: decl: %d\n",
00317 decl_num);
00318 # endif
00319 putw(p -> kind, Soutfile);
00320 sig_out1(Soutfile, p -> prod_local_type_id);
00321 putw(length(p -> prod_components), Soutfile);
00322 maplist(s, p -> prod_components, {
00323 sig_out1(Soutfile, s);
00324 });
00325 break;
00326
00327 case WORDELSE:
00328 putw(WORDELSE, Soutfile);
00329 break;
00330
00331 case PARAMETER:
00332 putw(PARAMETER, Soutfile);
00333 sig_out1(Soutfile, p -> par_id);
00334 sig_out1(Soutfile, p -> par_signature);
00335 break;
00336
00337 case FUNCSIGNATURE:
00338
00339 if (p -> fsig_inline_code == NIL
00340 && p -> fsig_construction != NIL) {
00341 p -> fsig_inline_code = p -> fsig_construction
00342 -> signature
00343 -> fsig_inline_code;
00344 }
00345 putw(FUNCSIGNATURE, Soutfile);
00346 putw(p -> fsig_special, Soutfile);
00347 if (Gflag) {
00348 put_RIC(p -> fsig_inline_code, Soutfile);
00349 } else {
00350 put_string(Soutfile, p -> fsig_inline_code);
00351 }
00352
00353 maplist(s, p -> fsig_param_list, {
00354 add_decl(s);
00355 IFTRACE_DECL(
00356 printf("Parameter: %s, decl: %d\n",
00357 (s -> par_id == NIL? "(anon)" :
00358 getname(s -> par_id -> id_str_table_index)),
00359 decl_num);
00360 )
00361 });
00362 putw(length(p -> fsig_param_list), Soutfile);
00363 maplist(s, p -> fsig_param_list, {
00364 sig_out1(Soutfile, s);
00365 });
00366 sig_out1(Soutfile, p -> fsig_result_sig);
00367
00368 # define CONSTR_UNKNOWN 0
00369 # define CONSTR_AVAIL 1
00370 # define SLINK_AVAIL 2
00371 if (p -> fsig_construction == NIL) {
00372 putw(CONSTR_UNKNOWN, Soutfile);
00373 } else {
00374 NODE * constr = p -> fsig_construction;
00375
00376 if (p -> fsig_slink_known) {
00377 putw(SLINK_AVAIL, Soutfile);
00378 } else {
00379 putw(CONSTR_AVAIL, Soutfile);
00380 }
00381 putw(constr -> fc_complexity, Soutfile);
00382 # ifdef VERBOSE
00383 unparse_file = stdout;
00384 printf("Signature: ");
00385 unparse(p);
00386 printf(" bound to construction %s\n",
00387 constr -> fc_code_label);
00388 # endif
00389 put_string(Soutfile, constr -> fc_code_label);
00390 putw(constr -> ar_static_level, Soutfile);
00391 putw(constr -> ar_size, Soutfile);
00392 }
00393 break;
00394
00395 case VALSIGNATURE:
00396 putw(VALSIGNATURE, Soutfile);
00397 sig_out1(Soutfile, p -> val_denotation);
00398 break;
00399
00400 case VARSIGNATURE:
00401 putw(VARSIGNATURE, Soutfile);
00402 sig_out1(Soutfile, p -> var_denotation);
00403 break;
00404
00405 case SIGNATURESIG:
00406 putw(SIGNATURESIG, Soutfile);
00407 break;
00408
00409 case TYPESIGNATURE:
00410 add_decl(p);
00411 # ifdef TRACE_DECL
00412 printf("Type signature: decl: %d\n",
00413 decl_num);
00414 unparse_file = stdout;
00415 unparse(p);
00416 printf("\n");
00417 # endif
00418 putw(TYPESIGNATURE, Soutfile);
00419 sig_out1(Soutfile, p -> ts_local_type_id);
00420 putw(length(p -> ts_clist), Soutfile);
00421 maplist(s, p -> ts_clist, {
00422 sig_out1(Soutfile, s);
00423 });
00424
00425 put_string(Soutfile, p -> ts_const_code);
00426 put_string(Soutfile, p -> ts_string_code);
00427 put_string(Soutfile, p -> ts_element_code);
00428 putw(p -> ts_string_max, Soutfile);
00429 putw(p -> ts_simple_type, Soutfile);
00430 # ifdef TRACE_DECL
00431 printf("Finished type signature\n");
00432 # endif
00433 break;
00434
00435 case TSCOMPONENT:
00436 putw(TSCOMPONENT, Soutfile);
00437 sig_out1(Soutfile, p -> tsc_id);
00438 sig_out1(Soutfile, p -> tsc_signature);
00439 break;
00440
00441 case DEFCHARSIGS:
00442 {
00443 int i;
00444 unsigned * base = &(p -> dcs_0);
00445
00446 putw(DEFCHARSIGS, Soutfile);
00447 for(i = 0; i < NVECTORS; i++) {
00448 putw(base[i], Soutfile);
00449 }
00450 }
00451 break;
00452
00453 case REXTERNDEF:
00454 putw(REXTERNDEF, Soutfile);
00455 put_string(Soutfile, p -> r_ext_name);
00456 break;
00457
00458 case RECORDCONSTRUCTION:
00459 case EXTENSION:
00460 case ENUMERATION:
00461 case RECORDELEMENT:
00462 case WITHLIST:
00463 case EXPORTLIST:
00464 case HIDELIST:
00465 case EXPORTELEMENT:
00466 dbgmsg("Signature output can't handle %s yet\n",
00467 kindname(p -> kind));
00468 break;
00469
00470 case LISTHEADER:
00471 case FREEVARNODE:
00472 case WORDCAND:
00473 case WORDCOR:
00474 case EXTERNDEF:
00475 default:
00476 dbgmsg("sig_out: bad kind, kind = %d\n", p -> kind);
00477 abort();
00478
00479 };
00480 return;
00481 }