C:/Users/Dennis/src/lang/russell.orig/src/pass5d/type_constr.c

Go to the documentation of this file.
00001 # include "parm.h"
00002 # include <stdio.h>
00003 # include "stree/ststructs.mh"
00004 # include "codegen.h"
00005 # include "op_codes.h"
00006 
00007 void Ggen_special();
00008 
00009 # ifdef DEBUG
00010 #   define IFDEBUG(x) x
00011 # else
00012 #   define IFDEBUG(x)
00013 # endif
00014 
00015 extern int yydebug;
00016 extern int yynerrs;
00017 
00018 extern char str_code_buf[];
00019 
00020 extern int avail_loc;
00021 
00022 extern int Glevel;
00023 
00024 extern FILE * Goutfile;
00025 
00026 /* Generate code for the type construction p.  The type value is to
00027  * be left in rloc.
00028  */
00029 void type_constr(p, rloc)
00030 NODE *p;
00031 int rloc;
00032 {
00033     int env_loc;  /* pointer to pseudo environment for records */
00034     int i;
00035 
00036     if (p -> kind == EXTENSION) {
00037         int new_tp_ptr = avail_loc++;
00038         int old_tp_ptr = avail_loc++;
00039         int identity_loc = avail_loc++;
00040         int sz_loc = avail_loc++;
00041         int len = tsig_length(p -> signature);
00042 
00043         /* allocate an object of the right size for new type */
00044           gen2(DCL, sz_loc, DCL_INT);
00045           gen2(LDN, len, sz_loc);
00046           gen2(DCL, new_tp_ptr, DCL_ADDR);
00047           gen2(ALH, sz_loc, new_tp_ptr);
00048           gen1(UDC, sz_loc);
00049           gen2(MOV, new_tp_ptr, rloc);
00050         /* put "argument" value into old_tp_ptr */
00051           gen2(DCL, old_tp_ptr, DCL_ADDR);
00052           Gexpression(p -> ext_denotation, old_tp_ptr, FALSE);
00053         /* put identity function value in identity_loc    */
00054           gen2(DCL, identity_loc, DCL_ADDR);
00055           Ggen_special(special(IDENTITY, 0), identity_loc, 0);
00056         /* Fill in individual fields. new_tp_ptr points to */
00057         /* next field to be filled in.                     */
00058         /* old_tp_ptr points to next unused field in arg   */
00059           ASSERT(p -> In_index < p -> Out_index,
00060                  "type_constr: bad In, Out indicees\n");
00061           /* Copy up to In function */
00062             for (i = 0; i < p -> In_index; i++) {
00063               gen3(LDI, old_tp_ptr, i, T1);
00064               gen3(STI, new_tp_ptr, i, T1);
00065             }
00066           /* Put In function in place */
00067             gen3(STI, new_tp_ptr, p->In_index, identity_loc);
00068           /* Copy up to Out function */
00069             for (i = p -> In_index + 1; i < p -> Out_index; i++) {
00070               gen3(LDI, old_tp_ptr, i-1, T1); 
00071               gen3(STI, new_tp_ptr, i, T1);
00072             }
00073           /* Put Out function in place */
00074             gen3(STI, new_tp_ptr, p -> Out_index, identity_loc);
00075           /* Copy the rest */
00076             for (i = p -> Out_index + 1; i < len; i++) {
00077               gen3(LDI, old_tp_ptr, i-2, T1); 
00078               gen3(STI, new_tp_ptr, i, T1);
00079             }
00080         /* new type value is already in rloc */
00081         /* undeclare temporaries */
00082             gen1(UDC, new_tp_ptr);
00083             gen1(UDC, old_tp_ptr);
00084             gen1(UDC, identity_loc);
00085         return;
00086     }
00087     if (p -> kind == RECORDCONSTRUCTION) {
00088         int n_components = length(p -> rec_component_list);
00089         int i;
00090         int sz_loc = avail_loc++;
00091         int tp_loc = avail_loc++;  /* pseudo-environment */
00092         int tmp_loc = avail_loc++;
00093 
00094         env_loc = avail_loc++;
00095         /* Allocate "environment" object for New, := and V */
00096         /* This is a vector of these 3 functions for each  */
00097         /* component.                                      */
00098           gen2(DCL, sz_loc, DCL_INT);
00099           gen2(DCL, env_loc, DCL_ADDR);
00100           gen2(LDN, 3*n_components, sz_loc);
00101           gen2(ALH, sz_loc, env_loc);
00102           gen1(UDC, sz_loc);
00103         /* Fill in fields in "environment"       */
00104           i = 0;  /* Position in p. e. */
00105           maplist(s, p -> rec_component_list, {
00106             /* evaluate field type into tmp_loc */
00107               gen2(DCL, tp_loc, DCL_ADDR);
00108               Gexpression(s -> re_denotation, tp_loc, FALSE);
00109             /* copy assignment operator to p. e. */
00110               gen2(DCL, tmp_loc, DCL_INT);
00111               gen3(LDI, tp_loc, s -> re_assign_index, tmp_loc);
00112               gen3(STI, env_loc, i, tmp_loc);
00113               gen1(UDC, tmp_loc);
00114             /* copy New operator */
00115               gen2(DCL, tmp_loc, DCL_INT);
00116               gen3(LDI, tp_loc, s -> re_New_index, tmp_loc);
00117               gen3(STI, env_loc, i+1, tmp_loc);
00118               gen1(UDC, tmp_loc);
00119             /* copy ValueOf operator */
00120               gen2(DCL, tmp_loc, DCL_INT);
00121               gen3(LDI, tp_loc, s -> re_ValueOf_index, tmp_loc);
00122               gen3(STI, env_loc, i+2, tmp_loc);
00123               gen1(UDC, tmp_loc);
00124             i += 3;
00125             gen1(UDC, tp_loc);
00126           });
00127         /* env_loc points to pseudo-environment */
00128         /* Proceed as with other constructions: */
00129     }
00130     {
00131         NODE * clist = p -> signature -> ts_clist;
00132         int len = tsig_length(p -> signature);
00133         int sz_loc = avail_loc++;
00134         int tmp_loc = avail_loc++;
00135 
00136         /* allocate a new type object */
00137           gen2(DCL, sz_loc, DCL_INT);
00138           gen2(LDN, len, sz_loc);
00139           gen2(ALH, sz_loc, rloc);
00140           gen1(UDC, sz_loc);
00141         /* pointer to new type object is in tp_loc  */
00142         /* Fill in individual fields:               */
00143           i = 0; /* Position to be filled in next; */
00144           /* First take care of 1 character constants in enumerations */
00145             {
00146                 NODE * dcs = first(clist);
00147 
00148                 ASSERT(dcs -> kind == DEFCHARSIGS, "type_const: bad DCS node\n");
00149                 if (dcs -> dcs_exceptions != NIL) {
00150                   maplist(s, dcs -> dcs_exceptions, {
00151                     gen2(DCL, tmp_loc, DCL_INT);
00152                     Ggen_special(s -> dcse_special,
00153                                 tmp_loc, env_loc);
00154                     gen3(STI, rloc, i++, tmp_loc);
00155                     gen1(UDC, tmp_loc);
00156                   });
00157                 }
00158             }
00159           maplist(s, clist, {
00160             switch(s -> kind) {
00161                 case TSCOMPONENT:
00162                     gen2(DCL, tmp_loc, DCL_INT);
00163                     Ggen_special(s -> tsc_signature -> fsig_special,
00164                                 tmp_loc, env_loc);
00165                     gen3(STI, rloc, i++, tmp_loc);
00166                     gen1(UDC, tmp_loc);
00167                     break;
00168               IFDEBUG(
00169                 case DEFCHARSIGS:
00170                     /* no constants */
00171                     break;
00172                 default:
00173                     dbgmsg("type_constr: bad type constr. sig\n");
00174               )
00175             }
00176           });
00177     }
00178     if (p -> kind == RECORDCONSTRUCTION) {
00179       /* Undeclare pseudo-environment location */
00180         gen1(UDC, env_loc);
00181     }
00182 }
00183 
00184 /* Compute the function value associated with the given special value */
00185 /* Leave the result in rloc.                                          */
00186 /* If a nontrivial pseudo-environment is needed, it is presumed to be */
00187 /* in pe_loc.                                                         */
00188 void Ggen_special(spcl, rloc, pe_loc)
00189 unsigned spcl;
00190 int rloc;
00191 int pe_loc;
00192 {
00193     char * routine_name;  /* name of routine for each operation */
00194     int n_args;           /* number of arguments to routine     */
00195     boolean explicit_ep = FALSE;  /* pseudo-env to be obtained from pe_loc */
00196     int tmp_loc = avail_loc++;
00197 
00198     /* Find routine name and n_args */
00199     /* Note that some of the runtime routines need gross hacks */
00200     /* in order to look at environment information             */
00201         switch(special_tp(spcl)) {
00202             case PROD_PROJ:
00203             case RECORD_VAL_FIELD:
00204             case RECORD_VAR_FIELD:
00205                 routine_name = "_P_R_ith";
00206                 n_args = 1;
00207                 break;
00208 
00209             case RECORD_MK:
00210             case PROD_MK:
00211                 routine_name = "_P_R_Make";
00212                     /* Needs hack in runtime code to deal with */
00213                     /* varying numbers of arguments.           */
00214                 n_args = special_val(spcl);
00215                 break;
00216 
00217             case PROD_NEW:
00218             case UNION_NEW:
00219                 routine_name = "_P_U_New";
00220                 n_args = 0;
00221                 break;
00222 
00223             case RECORD_NEW:
00224                 routine_name = "_Record_New";
00225                 n_args = 0;
00226                 explicit_ep = TRUE;
00227                 break;
00228 
00229             case ENUM_NEW:
00230                 routine_name = "_E_New";
00231                 n_args = 0;
00232                 break;
00233 
00234             case PROD_ASSIGN:
00235             case UNION_ASSIGN:
00236             case ENUM_ASSIGN:
00237                 routine_name = "_CF_PUE_Assign";
00238                 n_args = 2;
00239                 break;
00240 
00241             case RECORD_ASSIGN:
00242                 routine_name = "_Record_Assign";
00243                 n_args = 2;
00244                 explicit_ep = TRUE;
00245                 break;
00246     
00247             case PROD_VALUEOF:
00248             case UNION_VALUEOF:
00249             case ENUM_VALUEOF:
00250                 routine_name = "_CF_PUE_ValueOf";
00251                 n_args = 1;
00252                 break;
00253       
00254             case RECORD_VALUEOF:
00255                 routine_name = "_Record_ValueOf";
00256                 n_args = 1;
00257                 explicit_ep = TRUE;
00258                 break;
00259 
00260             case UNION_PROJ:
00261                 routine_name = "_Union_Proj";
00262                 n_args = 1;
00263                 break;
00264     
00265             case UNION_INJ:
00266                 routine_name = "_Union_Inj";
00267                 n_args = 1;
00268                 break;
00269 
00270             case UNION_INQ:
00271                 routine_name = "_Union_Inq";
00272                 n_args = 1;
00273                 break;
00274 
00275             case ENUM_EQ:
00276                 routine_name = "_CF_Enum_eq";
00277                 n_args = 2;
00278                 break;
00279 
00280             case ENUM_NE:
00281                 routine_name = "_CF_Enum_ne";
00282                 n_args = 2;
00283                 break;
00284 
00285             case ENUM_ELEMENT:
00286                 routine_name = "_Enum_Element";
00287                 n_args = 0;
00288                 break;
00289 
00290             case ENUM_CARD:
00291                 routine_name = "_Enum_Card";
00292                 n_args = 0;
00293                 break;
00294 
00295             case ENUM_PRED:
00296                 routine_name = "_CF_Enum_Pred";
00297                 n_args = 1;
00298                 break;
00299 
00300             case ENUM_SUCC:
00301                 routine_name = "_Enum_Succ";
00302                 n_args = 1;
00303                 break;
00304 
00305             case IDENTITY:
00306                 routine_name = "_CF_Identity";
00307                 n_args = 1;
00308                 break;
00309 
00310 #         ifdef DEBUG
00311             default:
00312                dbgmsg("Ggen_special: Unknown special function\n");
00313 #         endif
00314         }
00315     /* allocate new function object */
00316         ALLOC_FO(rloc);
00317         if (!explicit_ep) {
00318           /* Use special value as ep */
00319             gen2(DCL, tmp_loc, DCL_INT);
00320             gen2(LDN, special_val(spcl), tmp_loc);
00321             gen3(STI, rloc, FO_EP, tmp_loc);
00322             gen1(UDC, tmp_loc);
00323         } else {
00324             gen3(STI, rloc, FO_EP, pe_loc);
00325         }
00326     /* Set up ip */
00327         genl(EXT, routine_name);
00328         gen2(DCL, tmp_loc, DCL_ADDR);
00329         genl(LBA, routine_name);
00330         gen1(LDL, tmp_loc);
00331         gen3(STI, rloc, FO_IP, tmp_loc);
00332         gen1(UDC, tmp_loc);
00333     /* set activation record size to number of arguments plus 1 */
00334         gen2(DCL, tmp_loc, DCL_INT);
00335         gen2(LDN, n_args + 1, tmp_loc);
00336         gen3(STI, rloc, FO_SIZE, tmp_loc);
00337         gen1(UDC, tmp_loc);
00338 }
00339 

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