C:/Users/Dennis/src/lang/russell.orig/src/sigio/sa_sig_in.c

Go to the documentation of this file.
00001 /* A version of sig_in.c that does the best it can without access to */
00002 /* the initenv syntax tree.                                          */
00003 #define TRACE
00004 #undef TRACE
00005 #define DEBUG
00006 #undef DEBUG
00007 /* Routines to read in a signature and optimization information */
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  /* exit code if file contents dont look like syntax tree */
00020 # define MAXLISTELMTS 100000  /* Maximum palusible list length */
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;  /* name of last Sinfile passed to sig_in */
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;       /* list of declaration nodes and corresponding numbers */
00035                     /* This is a silly data structure, but the list is     */
00036                     /* unlikely to have length > 1                         */
00037 
00038 static int decl_num = 0;  /* last number assigned to a declaration */
00039 
00040 /* Add a new declaration to decl_nums.  Assign it the next available number */
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 /* Get the node associated with declnum.  Return NONE if there isn't any */
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 /* free decl_nums structure */
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]; /* used as string temporary */
00082 
00083 /* Read a 0 terminated string from Sinfile.
00084  * A NIL pointer is represented as a string consisting of a single FF
00085  * (delete) character.
00086  * Allocate space for the string and return a pointer to the heap
00087  * object.
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 /* Read a word from Sinfile, and check for errors */
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 /* Identifiers are written out as
00143  *              kind
00144  *              representation kind
00145  *              selection expression (if any)
00146  *              declaration number (local) or address (global)
00147  *                                 (not used for selection)
00148  *              name (0 terminated string, empty if local type id)
00149  *
00150  * The following options exist for the representation kind field:
00151  */
00152 # define LOCALREP  0
00153 # define GLOBALREP 1
00154 # define SELECTREP 2 
00155 
00156 /* Read an identifier.  Return a pointer to the corresponding id node */
00157 /* It is assumed that the kind field has already been read.           */
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     /* Read identifier name */
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 /* Read in a list of expression (or signature) trees from Sinfile     */
00243 /* The next number on Sinfile is assumed to be the number of elements */
00244 /* in the list.                                                       */
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 /* Read an expression tree from Sinfile.  Return a pointer to the tree.    */
00267 /* This is the same representation used by sig_out. It is designed to be   */
00268 /* relatively efficient.  Local identifiers are represented by the number  */
00269 /* of their declaration.  Such numbers are assigned in preorder fashion.   */
00270 /* This may theoretically build an incorrectly structured tree, if it      */
00271 /* is asked to read a file not produced by sig_out.                        */
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                     /* First add dummy declaration nodes to decl_nums */
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) /* in-line code */
00496                                      : get_string(Sinfile)),
00497                                     NIL, NIL);
00498                     result -> fsig_special = spcl;
00499 
00500                     /* Read number of parameters and add blank nodes to */
00501                     /* decl_nums.                                       */
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                     /* Fill in parameter nodes */
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                     /* Restore info about function construction */
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                             /* and continue: */
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                 /* recover optimization information: */
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 }

Generated on Fri Jan 25 10:39:48 2008 for russell by  doxygen 1.5.4