|
|
1.1 ! root 1: #ifndef lint ! 2: static char sccsid[] = "@(#)sem.c 4.1 (Berkeley) 7/3/83"; ! 3: #endif ! 4: ! 5: #include "Courier.h" ! 6: ! 7: /* ! 8: * String allocation. ! 9: */ ! 10: char * ! 11: copy(s) ! 12: char *s; ! 13: { ! 14: char *p; ! 15: extern char *malloc(); ! 16: ! 17: if ((p = malloc(strlen(s) + 1)) == NULL) { ! 18: fprintf(stderr, "Out of string space.\n"); ! 19: exit(1); ! 20: } ! 21: strcpy(p, s); ! 22: return (p); ! 23: } ! 24: ! 25: /* ! 26: * Object allocation. ! 27: */ ! 28: struct object * ! 29: make(class, value) ! 30: enum class class; ! 31: int value; ! 32: { ! 33: struct object *o; ! 34: ! 35: o = New(struct object); ! 36: o->o_class = class; ! 37: switch (class) { ! 38: case O_TYPE: ! 39: o->o_type = New(struct type); ! 40: o->t_constr = (enum constr) value; ! 41: break; ! 42: case O_SYMBOL: ! 43: o->o_name = copy(value); ! 44: break; ! 45: case O_CONSTANT: ! 46: o->o_value = value; ! 47: break; ! 48: default: ! 49: yyerror("Internal error: bad object class %d", class); ! 50: exit(1); ! 51: } ! 52: return (o); ! 53: } ! 54: ! 55: /* ! 56: * Lisp operations. ! 57: */ ! 58: list ! 59: cons(a, b) ! 60: list a, b; ! 61: { ! 62: list p; ! 63: ! 64: if ((p = New(struct cons)) == NIL) { ! 65: yyerror("Out of cons space."); ! 66: exit(1); ! 67: } ! 68: car(p) = a; ! 69: cdr(p) = b; ! 70: return (p); ! 71: } ! 72: ! 73: length(p) ! 74: list p; ! 75: { ! 76: int n; ! 77: ! 78: for (n = 0; p != NIL; p = cdr(p), n++) ! 79: ; ! 80: return (n); ! 81: } ! 82: ! 83: list ! 84: nconc(p, q) ! 85: list p, q; ! 86: { ! 87: list pp; ! 88: ! 89: pp = p; ! 90: if (p == NIL) ! 91: return (q); ! 92: while (cdr(p) != NIL) ! 93: p = cdr(p); ! 94: cdr(p) = q; ! 95: return (pp); ! 96: } ! 97: ! 98: struct object * ! 99: construct_type1(constructor, items) ! 100: enum constr constructor; ! 101: list items; ! 102: { ! 103: struct object *t; ! 104: ! 105: t = make(O_TYPE, constructor); ! 106: t->t_list = items; ! 107: return (t); ! 108: } ! 109: ! 110: struct object * ! 111: construct_type2(constructor, size, base) ! 112: enum constr constructor; ! 113: struct object *size, *base; ! 114: { ! 115: struct object *t; ! 116: ! 117: t = make(O_TYPE, constructor); ! 118: t->t_basetype = base; ! 119: t->t_size = size; ! 120: return (t); ! 121: } ! 122: ! 123: struct object * ! 124: construct_procedure(args, results, errors) ! 125: list args, results, errors; ! 126: { ! 127: struct object *t; ! 128: ! 129: t = make(O_TYPE, C_PROCEDURE); ! 130: t->t_args = args; ! 131: t->t_results = results; ! 132: t->t_errors = errors; ! 133: return (t); ! 134: } ! 135: ! 136: /* ! 137: * Look up the value corresponding to a member of an enumeration type. ! 138: * Print an error message if it's not found. ! 139: */ ! 140: struct object * ! 141: designator_value(symbol, enumtype) ! 142: struct object *symbol, *enumtype; ! 143: { ! 144: list p; ! 145: char *name; ! 146: ! 147: name = symbol->o_name; ! 148: for (p = enumtype->t_list; p != NIL; p = cdr(p)) ! 149: if (streq(name, name_of(car(car(p))))) ! 150: return ((struct object *) cdr(car(p))); ! 151: yyerror("%s not a member of specified enumeration type", name); ! 152: return (0); ! 153: } ! 154: ! 155: /* ! 156: * Construct a choice type. ! 157: * There are two ways a choice can be specified: ! 158: * with an explicit designator enumeration type, ! 159: * or implicitly by specifying values for each designator. ! 160: * Convert the second form into the first by creating ! 161: * an enumeration type on the fly. ! 162: */ ! 163: struct object * ! 164: construct_choice(designator, candidates) ! 165: struct object *designator; ! 166: list candidates; ! 167: { ! 168: struct object *t; ! 169: list p, q, dlist; ! 170: int bad = 0; ! 171: ! 172: if (designator != 0) { ! 173: t = basetype(designator); ! 174: if (t->t_constr != C_ENUMERATION) { ! 175: yyerror("Designator type %s is not an enumeration type", ! 176: designator->o_name); ! 177: return (Unspecified_type); ! 178: } ! 179: /* check that designators don't specify values */ ! 180: for (p = candidates; p != NIL; p = cdr(p)) ! 181: for (q = car(car(p)); q != NIL; q = cdr(q)) { ! 182: if (cdr(car(q)) != NIL) { ! 183: yyerror("Value cannot be specified for designator %s", ! 184: name_of(car(car(q)))); ! 185: bad = 1; ! 186: continue; ! 187: } ! 188: if (designator_value(car(car(q)), t) == 0) { ! 189: bad = 1; ! 190: continue; ! 191: } ! 192: } ! 193: } else { ! 194: /* check that designators do specify values */ ! 195: dlist = NIL; ! 196: for (p = candidates; p != NIL; p = cdr(p)) ! 197: for (q = car(car(p)); q != NIL; q = cdr(q)) { ! 198: if (cdr(car(q)) == NIL) { ! 199: yyerror("Value must be specified for designator %s", ! 200: name_of(car(car(q)))); ! 201: bad = 1; ! 202: continue; ! 203: } ! 204: dlist = cons(car(q), dlist); ! 205: } ! 206: if (! bad) ! 207: designator = construct_type1(C_ENUMERATION, dlist); ! 208: } ! 209: if (bad) ! 210: return (Unspecified_type); ! 211: t = make(O_TYPE, C_CHOICE); ! 212: t->t_designator = designator; ! 213: t->t_candidates = candidates; ! 214: return (t); ! 215: } ! 216: ! 217: /* ! 218: * Symbol table management. ! 219: */ ! 220: struct object * ! 221: lookup(symlist, symbol) ! 222: list symlist; ! 223: struct object *symbol; ! 224: { ! 225: char *name; ! 226: list p, q; ! 227: ! 228: name = symbol->o_name; ! 229: for (p = symlist; p != NIL; p = cdr(p)) { ! 230: q = car(p); ! 231: if (streq(name_of(car(q)), name)) ! 232: return ((struct object *) cdr(q)); ! 233: } ! 234: return (0); ! 235: } ! 236: ! 237: check_def(symbol) ! 238: struct object *symbol; ! 239: { ! 240: if (lookup(Values, symbol) == 0) { ! 241: yyerror("%s undefined", symbol->o_name); ! 242: return (0); ! 243: } ! 244: return (1); ! 245: } ! 246: ! 247: declare(symlist, name, value) ! 248: list *symlist; ! 249: struct object *name, *value; ! 250: { ! 251: if (lookup(*symlist, name) != 0) { ! 252: yyerror("%s redeclared", name->o_name); ! 253: return; ! 254: } ! 255: *symlist = cons(cons(name, value), *symlist); ! 256: } ! 257: ! 258: /* ! 259: * Find the underlying type of a type. ! 260: */ ! 261: struct object * ! 262: basetype(type) ! 263: struct object *type; ! 264: { ! 265: while (type != 0 && class_of(type) == O_SYMBOL) ! 266: type = lookup(Values, type); ! 267: if (type == 0 || class_of(type) != O_TYPE) { ! 268: yyerror("Internal error: bad class in basetype\n"); ! 269: exit(1); ! 270: } ! 271: return (type); ! 272: } ! 273: ! 274: /* ! 275: * Make sure a number is a valid constant for this type. ! 276: */ ! 277: type_check(type, value) ! 278: struct object *type, *value; ! 279: { ! 280: struct object *t, *v; ! 281: ! 282: if (class_of(type) != O_SYMBOL) ! 283: return (type->t_constr == C_PROCEDURE || ! 284: type->t_constr == C_ERROR); ! 285: /* ! 286: * Type is a symbol. ! 287: * Track down the actual type, and its closest name. ! 288: */ ! 289: while (type != 0 && class_of(type) == O_SYMBOL) { ! 290: t = type; ! 291: type = lookup(Values, type); ! 292: } ! 293: if (type == 0 || class_of(type) != O_TYPE) { ! 294: yyerror("Internal error: bad class in type_check\n"); ! 295: exit(1); ! 296: } ! 297: if (type->t_constr != C_PREDEF) ! 298: return (type->t_constr == C_PROCEDURE || ! 299: type->t_constr == C_ERROR); ! 300: /* ! 301: * Here we know that t is either a type ! 302: * or a symbol defined as a predefined type. ! 303: * Now find the type of the constant, if possible. ! 304: * If it is just a number, we don't check any further. ! 305: */ ! 306: if (class_of(value) == O_SYMBOL) ! 307: v = basetype(lookup(Types, value)); ! 308: else ! 309: v = 0; ! 310: return ((t == Cardinal_type || t == LongCardinal_type || ! 311: t == Integer_type || t == LongInteger_type || ! 312: t == Unspecified_type) && (v == 0 || v == type)); ! 313: } ! 314: ! 315: /* ! 316: * Debugging routines. ! 317: */ ! 318: symtabs() ! 319: { ! 320: printf("Values:\n"); prsymtab(Values); ! 321: printf("Types:\n"); prsymtab(Types); ! 322: } ! 323: ! 324: prsymtab(symlist) ! 325: list symlist; ! 326: { ! 327: list p; ! 328: char *s; ! 329: ! 330: for (p = symlist; p != NIL; p = cdr(p)) { ! 331: switch (class_of(cdr(car(p)))) { ! 332: case O_TYPE: ! 333: s = "type"; break; ! 334: case O_CONSTANT: ! 335: s = "constant"; break; ! 336: case O_SYMBOL: ! 337: s = "symbol"; break; ! 338: default: ! 339: s = "unknown class"; break; ! 340: } ! 341: printf("%s = [%s]\n", name_of(car(car(p))), s); ! 342: } ! 343: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.