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

Go to the documentation of this file.
00001 # define TRACE_DECL
00002 # undef TRACE_DECL
00003 
00004 /* Routines to write out a signature and optimization information */
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   /* Maximum number of nested extern { ... } 's */
00013 
00014 /* This assumes that putw can write a pointer */
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;       /* list of declaration nodes and corresponding numbers */
00032                     /* This is a silly data structure, but the list is     */
00033                     /* unlikely to have length > 1                         */
00034 
00035 static int decl_num = 0;  /* last number assigned to a declaration */
00036 
00037 /* Add a new declartion to decl_nums.  Assign it the next available number */
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 /* Get the number associated with decl.  Return NONE if there isn't any */
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 /* Write a 0 terminated string onto Soutfile.
00065  * A NIL pointer is represented as a string consisting of a single FF
00066  * (delete) character
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 /* Identifiers are written out as
00081  *              kind
00082  *              representation kind
00083  *              selection expression (if any)
00084  *              declaration number (local) or address (global)
00085  *                                 (not used for selection)
00086  *              name (0 terminated string, empty if local type id)
00087  *
00088  * The following options exist for the representation kind field:
00089  */
00090 # define LOCALREP  0
00091 # define GLOBALREP 1
00092 # define SELECTREP 2 
00093 
00094 /* Write out an identifier */
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         /* local type id is represented as empty string */
00156         putc(0, Soutfile);
00157     } else {
00158         put_string(Soutfile, getname(string_index));
00159     }
00160 }
00161 
00162 /* Write a representation of the expression tree headed by p onto Soutfile */
00163 /* This is the same representation used by sig_in.  It is designed to be   */
00164 /* relatively efficient.  Local identifiers are represented by the number  */
00165 /* of their declaration.  Such numbers are assigned in preorder fashion.   */
00166 /* Globally declared identifiers are saved as character strings.           */
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                 /* write representation of identifier */
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                     /* forgetting is unimportant here */
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                 /* Try to fill in in-line code, if not already there */
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                 /* Add parameters to declaration list */
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                 /* Preserve info about function construction if available */
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                 /* preserve optimization information: */
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 }

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