1: /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 2: 3: /* 4: $Header: b2tcP.c,v 1.4 85/08/22 16:57:02 timo Exp $ 5: */ 6: 7: /* polytype representation */ 8: 9: #include "b.h" 10: #include "b1obj.h" 11: #include "b2tcP.h" 12: 13: /* A polytype is a compound with two fields. 14: * The first field is a B text, and holds the typekind. 15: * If the typekind is 'Variable', the second field is 16: * a B text, holding the identifier of the variable; 17: * otherwise, the second field is a compound of sub(poly)types, 18: * indexed from 0 to one less then the number of subtypes. 19: */ 20: 21: #define Kin 0 22: #define Sub 1 23: #define Id Sub 24: #define Asc 0 25: #define Key 1 26: 27: #define Kind(u) ((typekind) *Field((value) (u), Kin)) 28: #define Psubtypes(u) (Field((value) (u), Sub)) 29: #define Ident(u) (*Field((value) (u), Id)) 30: 31: typekind var_kind; 32: typekind num_kind; 33: typekind tex_kind; 34: typekind lis_kind; 35: typekind tab_kind; 36: typekind com_kind; 37: typekind t_n_kind; 38: typekind l_t_kind; 39: typekind tlt_kind; 40: typekind err_kind; 41: 42: polytype num_type; 43: polytype tex_type; 44: polytype err_type; 45: polytype t_n_type; 46: 47: /* Making, setting and accessing (the fields of) polytypes */ 48: 49: Visible polytype mkt_polytype(k, nsub) typekind k; intlet nsub; { 50: value u; 51: 52: u = mk_compound(2); 53: *Field(u, Kin)= copy((value) k); 54: *Field(u, Sub)= mk_compound(nsub); 55: return ((polytype) u); 56: } 57: 58: Procedure putsubtype(sub, u, isub) polytype sub, u; intlet isub; { 59: *Field(*Psubtypes(u), isub)= (value) sub; 60: } 61: 62: typekind kind(u) polytype u; { 63: return (Kind(u)); 64: } 65: 66: intlet nsubtypes(u) polytype u; { 67: return (Nfields(*Psubtypes(u))); 68: } 69: 70: polytype subtype(u, i) polytype u; intlet i; { 71: return ((polytype) *Field(*Psubtypes(u), i)); 72: } 73: 74: polytype asctype(u) polytype u; { 75: return (subtype(u, Asc)); 76: } 77: 78: polytype keytype(u) polytype u; { 79: return (subtype(u, Key)); 80: } 81: 82: value ident(u) polytype u; { 83: return (Ident(u)); 84: } 85: 86: /* making new polytypes */ 87: 88: polytype mkt_number() { 89: return(p_copy(num_type)); 90: } 91: 92: polytype mkt_text() { 93: return(p_copy(tex_type)); 94: } 95: 96: polytype mkt_tn() { 97: return(p_copy(t_n_type)); 98: } 99: 100: polytype mkt_error() { 101: return(p_copy(err_type)); 102: } 103: 104: polytype mkt_list(s) polytype s; { 105: polytype u; 106: 107: u = mkt_polytype(lis_kind, 1); 108: putsubtype(s, u, Asc); 109: return (u); 110: } 111: 112: polytype mkt_table(k, a) polytype k, a; { 113: polytype u; 114: 115: u = mkt_polytype(tab_kind, 2); 116: putsubtype(a, u, Asc); 117: putsubtype(k, u, Key); 118: return (u); 119: } 120: 121: polytype mkt_lt(s) polytype s; { 122: polytype u; 123: 124: u = mkt_polytype(l_t_kind, 1); 125: putsubtype(s, u, Asc); 126: return (u); 127: } 128: 129: polytype mkt_tlt(s) polytype s; { 130: polytype u; 131: 132: u = mkt_polytype(tlt_kind, 1); 133: putsubtype(s, u, Asc); 134: return (u); 135: } 136: 137: polytype mkt_compound(nsub) intlet nsub; { 138: return mkt_polytype(com_kind, nsub); 139: } 140: 141: polytype mkt_var(id) value id; { 142: polytype u; 143: 144: u = mk_compound(2); 145: *Field(u, Kin)= copy((value) var_kind); 146: *Field(u, Id)= id; 147: return (u); 148: } 149: 150: Hidden value nnewvar; 151: 152: polytype mkt_newvar() { 153: value v; 154: v = sum(nnewvar, one); 155: release(nnewvar); 156: nnewvar = v; 157: return mkt_var(convert(nnewvar, No, No)); 158: } 159: 160: polytype p_copy(u) polytype u; { 161: return((polytype) copy((polytype) u)); 162: } 163: 164: Procedure p_release(u) polytype u; { 165: release((polytype) u); 166: } 167: 168: /* predicates */ 169: 170: bool are_same_types(u, v) polytype u, v; { 171: if (compare((value) Kind(u), (value) Kind(v)) NE 0) 172: return (No); 173: else if (t_is_var(Kind(u))) 174: return (compare(Ident(u), Ident(v)) EQ 0); 175: else 176: return ( 177: (nsubtypes(u) EQ nsubtypes(v)) 178: && 179: (compare(*Psubtypes(u), *Psubtypes(v)) EQ 0) 180: ); 181: } 182: 183: bool have_same_structure(u, v) polytype u, v; { 184: return( 185: (compare((value) Kind(u), (value) Kind(v)) EQ 0) 186: && 187: nsubtypes(u) EQ nsubtypes(v) 188: ); 189: } 190: 191: bool t_is_number(kind) typekind kind; { 192: return (compare((value) kind, (value) num_kind) EQ 0 ? Yes : No); 193: } 194: 195: bool t_is_text(kind) typekind kind; { 196: return (compare((value) kind, (value) tex_kind) EQ 0 ? Yes : No); 197: } 198: 199: bool t_is_tn(kind) typekind kind; { 200: return (compare((value) kind, (value) t_n_kind) EQ 0 ? Yes : No); 201: } 202: 203: bool t_is_error(kind) typekind kind; { 204: return (compare((value) kind, (value) err_kind) EQ 0 ? Yes : No); 205: } 206: 207: bool t_is_list(kind) typekind kind; { 208: return (compare((value) kind, (value) lis_kind) EQ 0 ? Yes : No); 209: } 210: 211: bool t_is_table(kind) typekind kind; { 212: return (compare((value) kind, (value) tab_kind) EQ 0 ? Yes : No); 213: } 214: 215: bool t_is_lt(kind) typekind kind; { 216: return (compare((value) kind, (value) l_t_kind) EQ 0 ? Yes : No); 217: } 218: 219: bool t_is_tlt(kind) typekind kind; { 220: return (compare((value) kind, (value) tlt_kind) EQ 0 ? Yes : No); 221: } 222: 223: bool t_is_compound(kind) typekind kind; { 224: return (compare((value) kind, (value) com_kind) EQ 0 ? Yes : No); 225: } 226: 227: bool t_is_var(kind) typekind kind; { 228: return (compare((value) kind, (value) var_kind) EQ 0 ? Yes : No); 229: } 230: 231: bool has_number(kind) typekind kind; { 232: if (compare(kind, num_kind) EQ 0 || compare(kind, t_n_kind) EQ 0) 233: return (Yes); 234: else 235: return (No); 236: } 237: 238: bool has_text(kind) typekind kind; { 239: if (compare(kind, tex_kind) EQ 0 || compare(kind, t_n_kind) EQ 0) 240: return (Yes); 241: else 242: return (No); 243: } 244: 245: bool has_lt(kind) typekind kind; { 246: if (compare(kind, l_t_kind) EQ 0 || compare(kind, tlt_kind) EQ 0) 247: return (Yes); 248: else 249: return (No); 250: } 251: 252: /* The table "typeof" maps the identifiers of the variables (B texts) 253: * to polytypes. 254: */ 255: 256: value typeof; 257: 258: Procedure repl_type_of(u, p) polytype u, p; { 259: replace((value) p, &typeof, Ident(u)); 260: } 261: 262: bool table_has_type_of(u) polytype u; { 263: return(in_keys(Ident(u), typeof)); 264: } 265: 266: polytype type_of(u) polytype u; { 267: return((polytype) *adrassoc(typeof, Ident(u))); 268: } 269: 270: polytype bottom_var(u) polytype u; { 271: polytype b; 272: 273: if (!t_is_var(Kind(u))) 274: return (u); 275: /* Kind(u) == Variable */ 276: while (table_has_type_of(u)) { 277: b = type_of(u); 278: if (t_is_var(Kind(b))) 279: u = b; 280: else 281: break; 282: } 283: /* Kind(u) == Variable && !table_has_type_of(u)*/ 284: return (u); 285: } 286: 287: Visible Procedure usetypetable(t) value t; { 288: typeof = t; 289: } 290: 291: Visible Procedure deltypetable() { 292: release(typeof); 293: } 294: 295: /* init */ 296: 297: Visible Procedure initpol() { 298: num_kind = mk_text("Number"); 299: num_type = mkt_polytype(num_kind, 0); 300: tex_kind = mk_text("Text"); 301: tex_type = mkt_polytype(tex_kind, 0); 302: t_n_kind = mk_text("TN"); 303: t_n_type = mkt_polytype(t_n_kind, 0); 304: err_kind = mk_text("Error"); 305: err_type = mkt_polytype(err_kind, 0); 306: 307: lis_kind = mk_text("List"); 308: tab_kind = mk_text("Table"); 309: com_kind = mk_text("Compound"); 310: l_t_kind = mk_text("LT"); 311: tlt_kind = mk_text("TLT"); 312: var_kind = mk_text("Variable"); 313: 314: nnewvar = zero; 315: }