1: #ifndef lint
   2: static char RCSid[] = "$Header: constantcode.c,v 2.0 85/11/21 07:21:32 jqj Exp $";
   3: #endif
   4: 
   5: /* $Log:	constantcode.c,v $
   6:  * Revision 2.0  85/11/21  07:21:32  jqj
   7:  * 4.3BSD standard release
   8:  *
   9:  * Revision 1.4  85/05/23  06:19:32  jqj
  10:  * *** empty log message ***
  11:  *
  12:  * Revision 1.4  85/05/23  06:19:32  jqj
  13:  * Public Beta-test version, released 24 May 1985
  14:  *
  15:  * Revision 1.3  85/03/26  06:09:41  jqj
  16:  * Revised public alpha-test version, released 26 March 1985
  17:  *
  18:  * Revision 1.2  85/03/11  16:38:56  jqj
  19:  * Public alpha-test version, released 11 March 1985
  20:  *
  21:  * Revision 1.1  85/02/15  13:55:18  jqj
  22:  * Initial revision
  23:  *
  24:  */
  25: 
  26: /*
  27:  * Generate code for constant declarations.
  28:  */
  29: 
  30: #include "compiler.h"
  31: 
  32: /*
  33:  * Generate code for constant declarations
  34:  */
  35: define_constant(name, typtr, value)
  36:     struct object *name;
  37:     struct type *typtr;
  38:     struct constant *value;
  39: {
  40:     char *fullname;
  41: 
  42:     name->o_class = O_CONSTANT;
  43:     name->o_constant = value;
  44:     fullname = make_full_name( name->o_module,
  45:                 name->o_modversion, name_of(name));
  46:     /*
  47: 	 * Check for simple case of Foo: TypeBaz = Mumble;
  48: 	 * where Mumble is another constant.  In this case,
  49: 	 * just use the existing declaration
  50: 	 */
  51:     if (value->cn_name != NULL) {
  52:         if (!recursive_flag) {
  53:             fprintf(header,"#define %s %s\n",
  54:                 fullname, value->cn_name);
  55:             /* open scope */
  56:             fprintf(header1,"#define %s %s\n",
  57:                 name_of(name), value->cn_name);
  58:         }
  59:         return;
  60:     }
  61:     /*
  62: 	 * We have to generate some code for this one.  We'll generate
  63: 	 * the declaration in the header file of a static variable
  64: 	 * initialized to the appropriate values.
  65: 	 */
  66:     value->cn_name = fullname;
  67:     if (recursive_flag)
  68:         return;     /* it's already been expanded elsewhere */
  69:     /* open scope */
  70:     fprintf(header1,"#define %s %s\n", name_of(name), fullname);
  71:     /* make sure the type is defined */
  72:     if (typename(typtr) == NULL) {
  73:         /* create an anonymous (not in symboltable) type and subtypes */
  74:         char * typenam;
  75:         typenam = gensym("T_cn");
  76:         code_type(typenam, typtr);
  77:         typename(typtr) = typenam;
  78:         }
  79:     /* depending on the type, generate appropriate initializer */
  80:     switch (typtr->type_constr) {
  81:     case C_PROCEDURE:
  82:         define_procedure_constant(name, typtr, value);
  83:         break;
  84:     case C_ERROR:
  85:         define_error_constant(name, typtr, value);
  86:         break;
  87:     case C_NUMERIC:
  88:     case C_BOOLEAN:
  89:     case C_STRING:
  90:     case C_ENUMERATION:
  91:         /* these are simple, since they can't include sequences */
  92:         fprintf(header, "\nstatic %s %s = {%s};\n",
  93:             typename(typtr), value->cn_name, value->cn_value);
  94:         break;
  95:     default:
  96:         /* the general case */
  97:         scan_for_sequences(typtr, value);   /* kludge */
  98:         fprintf(header, "\nstatic %s %s = ",
  99:                 typename(typtr), value->cn_name);
 100:         code_constant(typtr, value);
 101:         fprintf(header,";\n");
 102:         break;
 103:     }
 104:     return;
 105: }
 106: 
 107: 
 108: /*
 109:  * Generate client and server code for error constants
 110:  */
 111: define_error_constant(symbol,typtr,value)
 112:     struct object *symbol;
 113:     struct type *typtr;
 114:     struct constant *value;
 115: {
 116:     char *errvalue;
 117: 
 118:     if (recursive_flag)
 119:         return;     /* can't happen */
 120:     if (typtr->type_constr != C_ERROR)
 121:         error(FATAL, "internal error (define_error_constant): not an error");
 122:     if (value->cn_constr != C_NUMERIC) {
 123:         error(ERROR,"Values of ERRORs must be numeric");
 124:         errvalue = "-1";
 125:     }
 126:     else
 127:         errvalue = value->cn_value;
 128:     fprintf(header,"\n#define %s (ERROR_OFFSET+%s)\n\
 129: #define %sArgs %s\n",
 130:             value->cn_name, errvalue,
 131:             value->cn_name, typename(typtr));
 132:     fprintf(header1,"#define %sArgs %sArgs\n",
 133:             symbol->o_name, value->cn_name);
 134:     value->cn_constr = C_ERROR;
 135:     /* put this error in the constant's data structure */
 136:     /* also store this error on the global list */
 137:     if (typtr->type_list == NIL) {
 138:         value->cn_list = cons((list) errvalue, NIL);
 139:         Errors = cons( cons((list) value, NIL), Errors);
 140:     }
 141:     else {
 142:         value->cn_list = cons((list) errvalue, (list) typtr);
 143:         Errors = cons( cons((list) value, (list) typtr), Errors);
 144:     }
 145: }
 146: 
 147: /*
 148:  * recursively generate the code for a constant
 149:  */
 150: code_constant(typtr, value)
 151:     struct type *typtr;
 152:     struct constant *value;
 153: {
 154:     switch (typtr->type_constr) {
 155:     case C_NUMERIC:
 156:     case C_BOOLEAN:
 157:     case C_STRING:
 158:     case C_ENUMERATION:
 159:         if (value == (struct constant*) 0)
 160:           fprintf(header, "0");
 161:         else
 162:           fprintf(header, "%s", value->cn_value);
 163:         break;
 164:     case C_ARRAY:
 165:         code_array_constant(typtr,value);
 166:         break;
 167:     case C_SEQUENCE:
 168:         code_sequence_constant(typtr,value);
 169:         break;
 170:     case C_RECORD:
 171:         code_record_constant(typtr,value);
 172:         break;
 173:     case C_CHOICE:
 174:         code_choice_constant(typtr,value);
 175:         break;
 176:     case C_ERROR:
 177:         error(ERROR,"Error constants may not be part of a structure");
 178:         break;
 179:     case C_PROCEDURE:
 180:         error(ERROR,"Procedures may not be part of a structure");
 181:     }
 182: }
 183: 
 184: /*
 185:  * Given the name of a record field and a record constant, return
 186:  * the corresponding component of the record constant.
 187:  */
 188: static struct constant *
 189: findcomponent(name,recvalue)
 190:     char *name;
 191:     struct constant *recvalue;
 192: {
 193:     list p;
 194: 
 195:     if (recvalue->cn_constr != C_RECORD)
 196:         error(FATAL,"internal error (findcomponent): constant is of type %d",
 197:             recvalue->cn_constr);
 198:     for (p = recvalue->cn_list; p != NIL; p = cdr(p))
 199:         if (streq((char *) caar(p), name))
 200:             return((struct constant *) cdar(p));
 201:     return((struct constant *) 0);
 202: }
 203: 
 204: 
 205: /*
 206:  * kludge since PCC doesn't like initializations of the form
 207:  *   struct {int length; Seqtype *sequence} seq = {3,{1,2,3}};
 208:  * instead, use:
 209:  *   Seqtype anonymous[3] = {1,2,3};
 210:  *   struct {int length; Seqtype *sequence} seq = {3,anonymous};
 211:  * We have to generate the sequence value before we walk the constant.
 212:  */
 213: scan_for_sequences(typtr, value)
 214:     struct type *typtr;
 215:     struct constant *value;
 216: {
 217:     list p;
 218: 
 219:     switch (typtr->type_constr) {
 220:     case C_ARRAY:
 221:         for (p = value->cn_list; p != NIL; p = cdr(p))
 222:             scan_for_sequences(typtr->type_basetype,
 223:                        (struct constant *) car(p));
 224:         break;
 225:     case C_RECORD:
 226:         scan_record_for_sequences(typtr, value);
 227:         break;
 228:     case C_CHOICE:
 229:         scan_choice_for_sequences(typtr, value);
 230:         break;
 231:     case C_SEQUENCE:
 232:         for (p = value->cn_list; p != NIL; p = cdr(p))
 233:             scan_for_sequences(typtr->type_basetype,
 234:                        (struct constant *) car(p));
 235:         value->cn_seqvalname = gensym("S_v");
 236:         fprintf(header,"\nstatic %s %s[%d] = {\n\t",
 237:             typename(typtr->type_basetype), value->cn_seqvalname,
 238:             length(value->cn_list));
 239:         for (p = value->cn_list ; p != NIL ; p = cdr(p)) {
 240:             code_constant(typtr->type_basetype,
 241:                       (struct constant *) car(p));
 242:             if (cdr(p) != NIL)
 243:                 fprintf(header,",\n\t");
 244:         }
 245:         fprintf(header,"\n};\n");
 246:         break;
 247:     default:    /* other types don't have embedded sequences */
 248:         break;
 249:     }
 250: }
 251: 
 252: scan_record_for_sequences(typtr, value)
 253:     struct type *typtr;
 254:     struct constant *value;
 255: {
 256:     list p, q;
 257:     struct constant *component;
 258: 
 259:     for (p = typtr->type_list; p != NIL; p = cdr(p)) {
 260:         q = car(p);
 261:         component = findcomponent((char *) caar(q),value);
 262:         if (component != (struct constant *) 0)
 263:             scan_for_sequences((struct type *) cdr(q), component);
 264:     }
 265: }
 266: 
 267: /*ARGSUSED*/
 268: scan_choice_for_sequences(typtr, value)
 269:     struct type *typtr;
 270:     struct constant *value;
 271: {
 272:     /* constants of type CHOICE are not implemented */
 273: }
 274: 
 275: 
 276: code_array_constant(typtr, value)
 277:     struct type *typtr;
 278:     struct constant *value;
 279: {
 280:     list p;
 281:     int i;
 282: 
 283:     if (value == (struct constant *) 0) {
 284:         fprintf(header,"{0");
 285:         for (i = 1; i < typtr->type_size; i++)
 286:           fprintf(header,",0");
 287:         fprintf(header,"}");
 288:         return;
 289:     }
 290:     if (typtr->type_size != length(value->cn_list))
 291:         error(WARNING,"wrong number of constant elements specified for array");
 292:     fprintf(header,"\n\t{");
 293:     for (p = value->cn_list; p != NIL; p = cdr(p)) {
 294:         code_constant(typtr->type_basetype,(struct constant *) car(p));
 295:         if (cdr(p) != NIL)
 296:             fprintf(header,",");
 297:     }
 298:     fprintf(header,"}");
 299: }
 300: 
 301: code_choice_constant(typtr, value)
 302:     struct type *typtr;
 303:     struct constant *value;
 304: {
 305:     list p,q;
 306:     struct type *bt;
 307:     char *desigval;
 308:     struct object *name;
 309: 
 310:     if (value == (struct constant *)0)
 311:       desigval = "?";   /* caar(typtr->type_designator->type_list); */
 312:     else
 313:       desigval = (char *) car(value->cn_list);
 314:     fprintf(header,"\n\t{ %s", desigval);
 315:     /* find the corresponding arm of the choice */
 316:     bt = TNIL;
 317:     for (p = typtr->type_candidates; bt==TNIL && p!=NIL; p = cdr(p)) {
 318:         for (q = caar(p); bt==TNIL && q!=NIL; q = cdr(q)) {
 319:             name = (struct object *) caar(q);
 320:             if (streq(name->o_enum->en_name,desigval))
 321:                 bt = (struct type *) cdar(p);
 322:         }
 323:     }
 324:     if (bt == TNIL)
 325:         error(WARNING,"CHOICE designator %s is invalid here",desigval);
 326:     else if (bt != NilRecord_type)
 327:         error(WARNING,"Constants of type CHOICE are not supported");
 328: 
 329:     fprintf(header,"\n\t}");
 330: }
 331: 
 332: code_sequence_constant(typtr, value)
 333:     struct type *typtr;
 334:     struct constant *value;
 335: {
 336:     list p;
 337:     int l;
 338: 
 339:     if (value == (struct constant *)0 ||
 340:         (p = value->cn_list) == NIL) {
 341:         fprintf(header,"{0, 0}");
 342:         return;
 343:     }
 344:     l = length(p);
 345:     if (typtr->type_size < l)
 346:         error(WARNING,"too many constant elements specified for sequence");
 347:     fprintf(header,"{%d, %s}",l,value->cn_seqvalname);
 348: }
 349: 
 350: code_record_constant(typtr, value)
 351:     struct type *typtr;
 352:     struct constant *value;
 353: {
 354:     list p, q;
 355:     struct constant *component;
 356: 
 357:     fprintf(header,"{");
 358:     for (p = typtr->type_list; p != NIL; p = cdr(p)) {
 359:         q = car(p);
 360:         if (value == (struct constant *) 0)
 361:           component = value;
 362:         else
 363:           component = findcomponent((char *) caar(q), value);
 364:         code_constant((struct type *) cdr(q), component);
 365:         if (cdr(p) != NIL)
 366:             fprintf(header,",");
 367:     }
 368:     fprintf(header,"\n\t}");
 369: }

Defined functions

code_array_constant defined in line 276; used 1 times
code_choice_constant defined in line 301; used 1 times
code_constant defined in line 150; used 4 times
code_record_constant defined in line 350; used 1 times
code_sequence_constant defined in line 332; used 1 times
define_constant defined in line 35; used 1 times
define_error_constant defined in line 111; used 1 times
  • in line 85
findcomponent defined in line 188; used 2 times
scan_choice_for_sequences defined in line 268; used 1 times
scan_for_sequences defined in line 213; used 4 times
scan_record_for_sequences defined in line 252; used 1 times

Defined variables

RCSid defined in line 2; never used
Last modified: 1986-03-13
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 2013
Valid CSS Valid XHTML 1.0 Strict