|
|
1.1 ! root 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: } ! 370:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.