00001
00002
00003 #define TRACE
00004 #undef TRACE
00005 #define DEBUG
00006 #undef DEBUG
00007
00008
00009 # ifdef TRACE
00010 # define IFTRACE(x) x
00011 # else
00012 # define IFTRACE(x)
00013 # endif
00014
00015 # include "parm.h"
00016 # include <stdio.h>
00017 # include "stree/ststructs.mh"
00018 # include "pass3/is_local.h"
00019 # define FMTERR 7
00020 # define MAXLISTELMTS 100000
00021
00022 char FMTMSG[] = "Bad signature format for %s (not compiled with -c?)\n";
00023
00024 extern FILE * unparse_file;
00025
00026 char * Sinf_name;
00027
00028 extern boolean Gflag;
00029
00030 struct decl_entry {
00031 NODE * de_decl;
00032 int de_number;
00033 struct decl_entry * de_next;
00034 } *decl_nums;
00035
00036
00037
00038 static int decl_num = 0;
00039
00040
00041 # define add_decl(decl) { \
00042 struct decl_entry * o = malloc(sizeof (struct decl_entry)); \
00043 o -> de_number = (++decl_num); \
00044 o -> de_decl = decl; \
00045 o -> de_next = decl_nums; \
00046 decl_nums = o; \
00047 }
00048
00049 # define NONE -1
00050
00051
00052 static get_decl(decl_num)
00053 NODE * decl_num;
00054 {
00055 struct decl_entry *p = decl_nums;
00056
00057 while (p != NIL ) {
00058 if (decl_num == p -> de_number) {
00059 return(p -> de_decl);
00060 }
00061 p = p -> de_next;
00062 }
00063 return(NONE);
00064 }
00065
00066
00067 static free_decls()
00068 {
00069 struct decl_entry *p = decl_nums;
00070 struct decl_entry *q;
00071
00072 while (p != NIL ) {
00073 q = p;
00074 p = p -> de_next;
00075 free(q);
00076 }
00077 }
00078
00079 NODE * sig_in1();
00080
00081 extern char tokenbuf[1000];
00082
00083
00084
00085
00086
00087
00088
00089 char * get_string(Sinfile)
00090 FILE * Sinfile;
00091 {
00092 int len = 0;
00093 char c;
00094 char * result;
00095
00096 while((c = getc(Sinfile)) != 0) {
00097 if (ferror(Sinfile) || feof(Sinfile) || len >= (sizeof tokenbuf)-1) {
00098 fprintf(stderr, FMTMSG, Sinf_name);
00099 # ifdef TRACE
00100 printf("bad string\n");
00101 abort();
00102 # endif
00103 exit(FMTERR);
00104 }
00105 tokenbuf[len++] = c;
00106 }
00107 tokenbuf[len] = 0;
00108 if (len == 1 && tokenbuf[0] == '\377') {
00109 return(NIL);
00110 }
00111 result = malloc(len+1);
00112 strcpy(result, tokenbuf);
00113 return(result);
00114 }
00115
00116
00117 int readw(Sinfile)
00118 FILE * Sinfile;
00119 {
00120 int result;
00121
00122 if (ferror(Sinfile) || feof(Sinfile)) {
00123 fprintf(stderr, FMTMSG, Sinf_name);
00124 # ifdef TRACE
00125 printf("readw: read error\n");
00126 abort();
00127 # endif
00128 exit(FMTERR);
00129 }
00130 result = getw(Sinfile);
00131 if (ferror(Sinfile)) {
00132 fprintf(stderr, FMTMSG, Sinf_name);
00133 # ifdef TRACE
00134 printf("readw: read error\n");
00135 abort();
00136 # endif
00137 exit(FMTERR);
00138 }
00139 return(result);
00140 }
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152 # define LOCALREP 0
00153 # define GLOBALREP 1
00154 # define SELECTREP 2
00155
00156
00157
00158 NODE * get_name(Sinfile,kindno)
00159 FILE *Sinfile;
00160 int kindno;
00161 {
00162 unsigned string_index;
00163 int rep;
00164 NODE * selt = NIL;
00165 NODE * last_def = NIL;
00166 NODE * result;
00167 int decl_number;
00168
00169 # ifdef DEBUG
00170 if (kindno != LETTERID && kindno != OPRID) {
00171 dbgmsg("get_name: bad node kind\n");
00172 abort();
00173 }
00174 # endif
00175 rep = readw(Sinfile);
00176 switch(rep) {
00177 case SELECTREP:
00178 selt = sig_in1(Sinfile);
00179 break;
00180 case GLOBALREP:
00181 readw(Sinfile);
00182 last_def = NIL;
00183 break;
00184 case LOCALREP:
00185 decl_number = readw(Sinfile);
00186 last_def = get_decl(decl_number);
00187 if (last_def == NONE) {
00188 fprintf(stderr, FMTMSG, Sinf_name);
00189 # ifdef TRACE
00190 printf("No declaration %d\n", decl_number);
00191 abort();
00192 # endif
00193 exit(FMTERR);
00194 }
00195 break;
00196 }
00197 # ifdef DEBUG
00198 if (last_def != NIL &&
00199 last_def -> kind != DECLARATION &&
00200 last_def -> kind != PARAMETER &&
00201 last_def -> kind != TYPESIGNATURE &&
00202 last_def -> kind != PRODCONSTRUCTION &&
00203 last_def -> kind != UNIONCONSTRUCTION &&
00204 last_def -> kind != MODPRIMARY) {
00205 dbgmsg("get_name: bad definition %X\n", last_def);
00206 abort();
00207 }
00208 # endif
00209
00210 {
00211 int len = 0;
00212 char c;
00213
00214 while((c = getc(Sinfile)) != 0) {
00215 if (ferror(Sinfile) || feof(Sinfile) || len >= (sizeof tokenbuf)-1) {
00216 fprintf(stderr, FMTMSG, Sinf_name);
00217 # ifdef TRACE
00218 printf("error reading id name \n");
00219 abort();
00220 # endif
00221 exit(FMTERR);
00222 }
00223 tokenbuf[len++] = c;
00224 }
00225 tokenbuf[len] = 0;
00226 if (len == 0) {
00227 string_index = -1;
00228 } else {
00229 # ifdef TRACE
00230 printf("getname: read identifier name: %s\n", tokenbuf);
00231 # endif
00232 string_index = stt_enter(tokenbuf, len+1);
00233 }
00234 }
00235 result = mknode(kindno, string_index);
00236 result -> id_last_definition = last_def;
00237 initfld(&(result -> sel_type), selt);
00238 result -> id_def_found = TRUE;
00239 return(result);
00240 }
00241
00242
00243
00244
00245 NODE * list_in(Sinfile)
00246 FILE * Sinfile;
00247 {
00248 int nelements = readw(Sinfile);
00249 int i;
00250 NODE * result = emptylist();
00251
00252 if (((unsigned) nelements) > MAXLISTELMTS) {
00253 fprintf(stderr, FMTMSG, Sinf_name);
00254 # ifdef TRACE
00255 printf("absurdly long list\n");
00256 abort();
00257 # endif
00258 exit(FMTERR);
00259 }
00260 for (i = 0; i < nelements; i++) {
00261 addright(result, sig_in1(Sinfile));
00262 }
00263 return(result);
00264 }
00265
00266
00267
00268
00269
00270
00271
00272 NODE * sig_in(Sinfile, name)
00273 FILE * Sinfile;
00274 char * name;
00275 {
00276 NODE * result;
00277
00278 decl_nums = NIL;
00279 decl_num = 0;
00280 Sinf_name = name;
00281 result = sig_in1(Sinfile);
00282 # ifdef TRACE
00283 printf("Read signature\n");
00284 unparse_file = stdout;
00285 unparse(result);
00286 printf("\n");
00287 # endif
00288 free_decls();
00289 return(result);
00290 }
00291
00292 NODE * sig_in1(Sinfile)
00293 FILE * Sinfile;
00294 {
00295 register NODE * result;
00296 int kindno;
00297
00298 # ifdef TRACE
00299 printf("sig_in: position = %d\n", ftell(Sinfile));
00300 # endif
00301 kindno = readw(Sinfile);
00302 if (feof(Sinfile)) {
00303 # ifdef TRACE
00304 printf("End of file\n");
00305 abort();
00306 # endif
00307 fprintf(stderr, FMTMSG, Sinf_name);
00308 exit(FMTERR);
00309 }
00310 # ifdef TRACE
00311 printf("sig_in: kind = %d(%s)\n", kindno, kindname(kindno));
00312 # endif
00313
00314 switch ( kindno ) {
00315
00316 case -1:
00317 return(NIL);
00318
00319 case DECLARATION:
00320 {
00321 NODE * id;
00322 NODE * sig;
00323 NODE * den;
00324 int sig_transp;
00325 NODE * result;
00326
00327 id = sig_in1(Sinfile);
00328 sig_transp = readw(Sinfile);
00329 sig = sig_in1(Sinfile);
00330 den = sig_in1(Sinfile);
00331 result = mknode(DECLARATION, id, den, sig);
00332 result -> decl_sig_transp = sig_transp;
00333 return(result);
00334 }
00335
00336 case BLOCKDENOTATION:
00337 {
00338 NODE * decl_l;
00339 NODE * den_s;
00340 int len_decl_l = readw(Sinfile);
00341 int i;
00342 NODE * v;
00343
00344 if (((unsigned) len_decl_l) > MAXLISTELMTS) {
00345 fprintf(stderr, FMTMSG, Sinf_name);
00346 # ifdef TRACE
00347 printf("declaration list too long\n");
00348 abort();
00349 # endif
00350 exit(FMTERR);
00351 }
00352 decl_l = emptylist();
00353
00354 for (i = 0; i < len_decl_l; i++) {
00355 v = mknode(DECLARATION, NIL, NIL, NIL);
00356 addright(decl_l, v);
00357 add_decl(v);
00358 # ifdef TRACE
00359 printf("Added explicit declaration number %d\n",
00360 decl_num);
00361 # endif
00362 }
00363 maplist(v, decl_l, {
00364 int decl_kind;
00365 NODE * id;
00366 NODE * sig;
00367 NODE * den;
00368
00369 decl_kind = readw(Sinfile);
00370 if (decl_kind != DECLARATION) {
00371 fprintf(stderr, FMTMSG, Sinf_name);
00372 IFTRACE(
00373 printf("bad declaration\n");
00374 abort();
00375 )
00376 exit(FMTERR);
00377 }
00378 id = sig_in1(Sinfile);
00379 sig = sig_in1(Sinfile);
00380 den = sig_in1(Sinfile);
00381 initfld(&(v -> decl_id), id);
00382 initfld(&(v -> decl_denotation), den);
00383 initfld(&(v -> decl_signature), sig);
00384 });
00385 den_s = list_in(Sinfile);
00386 return(mknode(BLOCKDENOTATION, decl_l, den_s));
00387 }
00388
00389 case APPLICATION:
00390 {
00391 NODE * op;
00392 NODE * args;
00393
00394 op = sig_in1(Sinfile);
00395 args = list_in(Sinfile);
00396 return(mknode(APPLICATION, op, args));
00397 }
00398
00399 case LOOPDENOTATION:
00400 case GUARDEDLIST:
00401 return(mknode(kindno, list_in(Sinfile)));
00402
00403 case GUARDEDELEMENT:
00404 {
00405 NODE * guard;
00406 NODE * element;
00407
00408 guard = sig_in1(Sinfile);
00409 element = sig_in1(Sinfile);
00410 return(mknode(GUARDEDELEMENT, guard, element));
00411 }
00412
00413 case OPRID:
00414 case LETTERID:
00415 return(get_name(Sinfile, kindno));
00416
00417 case FUNCCONSTR:
00418 {
00419 NODE * sig;
00420 NODE * body;
00421
00422 sig = sig_in1(Sinfile);
00423 body = sig_in1(Sinfile);
00424 return(mknode(FUNCCONSTR, sig, body));
00425 }
00426
00427 case USELIST:
00428 {
00429 NODE * type_list;
00430 NODE * den_seq;
00431
00432 type_list = list_in(Sinfile);
00433 den_seq = list_in(Sinfile);
00434 return(mknode(USELIST, type_list, den_seq));
00435 }
00436
00437 case MODPRIMARY:
00438 {
00439 NODE * result = mknode(MODPRIMARY, NIL, NIL);
00440
00441 add_decl(result);
00442 # ifdef TRACE
00443 printf("Added mp declaration number %d\n",
00444 decl_num);
00445 # endif
00446 initfld(&(result -> mp_primary),
00447 sig_in1(Sinfile));
00448 initfld(&(result -> mp_type_modifier),
00449 sig_in1(Sinfile));
00450 return(result);
00451 }
00452
00453 case PRODCONSTRUCTION:
00454 case UNIONCONSTRUCTION:
00455 {
00456 NODE * result = mknode(kindno, NIL, NIL);
00457
00458 add_decl(result);
00459 # ifdef TRACE
00460 printf("Added type c. declaration number %d\n",
00461 decl_num);
00462 # endif
00463 initfld(&(result -> prod_local_type_id),
00464 sig_in1(Sinfile));
00465 initfld(&(result -> prod_components),
00466 list_in(Sinfile));
00467 return(result);
00468 }
00469
00470 case WORDELSE:
00471 return(mknode(WORDELSE));
00472
00473 case PARAMETER:
00474 {
00475 NODE * id;
00476 NODE * sig;
00477
00478 id = sig_in1(Sinfile);
00479 sig = sig_in1(Sinfile);
00480 return(mknode(PARAMETER, id, sig));
00481 }
00482
00483 case FUNCSIGNATURE:
00484 {
00485 NODE * param_list = emptylist();
00486 int nparams;
00487 int i, param_kind;
00488 int constr_info;
00489 NODE * constr;
00490 int spcl;
00491
00492 spcl = readw(Sinfile);
00493 result = mknode(FUNCSIGNATURE,
00494 (Gflag?
00495 get_RIC(Sinfile)
00496 : get_string(Sinfile)),
00497 NIL, NIL);
00498 result -> fsig_special = spcl;
00499
00500
00501
00502 nparams = readw(Sinfile);
00503 if (((unsigned) nparams) > MAXLISTELMTS) {
00504 fprintf(stderr, FMTMSG, Sinf_name);
00505 # ifdef TRACE
00506 printf("Too many parameters\n");
00507 # endif
00508 exit(FMTERR);
00509 }
00510 for (i = 0; i < nparams; i++) {
00511 NODE * v;
00512
00513 v = mknode(PARAMETER, NIL, NIL);
00514 addright(param_list, v);
00515 add_decl(v);
00516 # ifdef TRACE
00517 printf("Added parameter declaration number %d\n",
00518 decl_num);
00519 # endif
00520 }
00521
00522
00523 maplist(v, param_list, {
00524 param_kind = readw(Sinfile);
00525 if (param_kind != PARAMETER) {
00526 fprintf(stderr, FMTMSG, Sinf_name);
00527 IFTRACE(
00528 printf("bad parameter\n");
00529 abort();
00530 )
00531 exit(FMTERR);
00532 }
00533 initfld(&(v -> par_id), sig_in1(Sinfile));
00534 initfld(&(v -> par_signature), sig_in1(Sinfile));
00535 });
00536
00537 initfld(&(result -> fsig_param_list), param_list);
00538 initfld(&(result -> fsig_result_sig), sig_in1(Sinfile));
00539
00540 # define CONSTR_UNKNOWN 0
00541 # define CONSTR_AVAIL 1
00542 # define SLINK_AVAIL 2
00543 constr_info = readw(Sinfile);
00544 switch (constr_info) {
00545 case CONSTR_UNKNOWN:
00546 break;
00547
00548 case SLINK_AVAIL:
00549 result -> fsig_slink_known = TRUE;
00550
00551
00552 case CONSTR_AVAIL:
00553 constr = mknode(FUNCCONSTR,
00554 result,
00555 mknode(EXTERNDEF,NIL));
00556 lock(constr);
00557 result -> fsig_construction = constr;
00558 constr -> fc_complexity = readw(Sinfile);
00559 constr -> fc_code_label = get_string(Sinfile);
00560 constr -> ar_static_level = readw(Sinfile);
00561 constr -> ar_size = readw(Sinfile);
00562 # ifdef TRACE
00563 printf("Construction=%X, label=%s, compl=%d\n",
00564 constr, constr -> fc_code_label,
00565 constr -> fc_complexity);
00566 # endif
00567 }
00568 return(result);
00569 }
00570
00571 case VALSIGNATURE:
00572 case VARSIGNATURE:
00573 return(mknode(kindno, sig_in1(Sinfile)));
00574
00575 case SIGNATURESIG:
00576 return(mknode(SIGNATURESIG));
00577
00578 case TYPESIGNATURE:
00579 result = mknode(TYPESIGNATURE, NIL, NIL, NIL, NIL, NIL);
00580 add_decl(result);
00581 # ifdef TRACE
00582 printf("Added type sig. declaration number %d\n",
00583 decl_num);
00584 # endif
00585 initfld(&(result -> ts_local_type_id), sig_in1(Sinfile));
00586 initfld(&(result -> ts_clist), list_in(Sinfile));
00587
00588 result -> ts_const_code = get_string(Sinfile);
00589 result -> ts_string_code = get_string(Sinfile);
00590 result -> ts_element_code = get_string(Sinfile);
00591 result -> ts_string_max = readw(Sinfile);
00592 result -> ts_simple_type = readw(Sinfile);
00593 return(result);
00594
00595 case TSCOMPONENT:
00596 {
00597 NODE * id;
00598 NODE * sig;
00599
00600 id = sig_in1(Sinfile);
00601 sig = sig_in1(Sinfile);
00602 return(mknode(TSCOMPONENT, id, sig));
00603 }
00604
00605 case DEFCHARSIGS:
00606 {
00607 int i;
00608 unsigned * base;
00609
00610 result = mknode(DEFCHARSIGS, 0, 0, 0, 0);
00611 base = &(result -> dcs_0);
00612 for(i = 0; i < NVECTORS; i++) {
00613 base[i] = readw(Sinfile);
00614 }
00615 return(result);
00616 }
00617
00618 case REXTERNDEF:
00619 {
00620 NODE * sig = sig_in1(Sinfile);
00621 char * name = get_string(Sinfile);
00622
00623 result = mknode(REXTERNDEF, sig, name);
00624 result -> sig_done = SIG_DONE;
00625 return(result);
00626 }
00627
00628 case RECORDCONSTRUCTION:
00629 case EXTENSION:
00630 case ENUMERATION:
00631 case RECORDELEMENT:
00632 case WITHLIST:
00633 case EXPORTLIST:
00634 case HIDELIST:
00635 case EXPORTELEMENT:
00636 dbgmsg("Signature input can't handle %s yet\n",
00637 kindname(kindno));
00638 return(NIL);
00639
00640 case QSTR:
00641 case UQSTR:
00642 case LISTHEADER:
00643 case FREEVARNODE:
00644 case WORDCAND:
00645 case WORDCOR:
00646 case EXTERNDEF:
00647 default:
00648 # ifdef TRACE
00649 printf("Bad kind\n");
00650 abort();
00651 # endif
00652 fprintf(stderr, FMTMSG, Sinf_name);
00653 exit(FMTERR);
00654
00655 };
00656 }