00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #ifndef lint
00027 static char vcid[] = "$Id: lub.c,v 1.3 1995/08/25 21:34:37 duchier Exp $";
00028 #endif
00029
00030 #include "extern.h"
00031 #include "login.h"
00032 #include "trees.h"
00033 #include "print.h"
00034 #include "memory.h"
00035 #include "error.h"
00036 #include "token.h"
00037
00038 extern ptr_definition built_in;
00039
00040 ptr_int_list appendIntList(tail, more)
00041 ptr_int_list tail;
00042 ptr_int_list more;
00043 {
00044 while (more)
00045 {
00046 tail->next = STACK_ALLOC(int_list);
00047 tail= tail->next;
00048 tail->value = more->value;
00049 tail->next = NULL;
00050 more = more->next;
00051 }
00052 return tail;
00053 }
00054
00055
00056 void
00057 mark_ancestors(def, flags)
00058 ptr_definition def;
00059 long *flags;
00060 {
00061 ptr_int_list par;
00062
00063 par=def->parents;
00064 while (par) {
00065 ptr_definition p;
00066 long len;
00067
00068 p=(ptr_definition)par->value;
00069 len=bit_length(p->code);
00070 if (!flags[len]) {
00071 flags[len]=1;
00072 mark_ancestors(p, flags);
00073 }
00074 par=par->next;
00075 }
00076 }
00077
00078 static long bfs(p, ans, pattern, flags)
00079 ptr_definition p;
00080 ptr_int_list ans;
00081 ptr_int_list pattern;
00082 long *flags;
00083 {
00084 ptr_int_list head = STACK_ALLOC(int_list);
00085 ptr_int_list tail;
00086 ptr_int_list par;
00087 long len;
00088 long found = 0;
00089
00090 if (p == top)
00091 {
00092 or_codes(ans, top);
00093 return;
00094 }
00095
00096
00097
00098
00099 par = p->parents;
00100 if (par == NULL)
00101 return 0;
00102
00103 assert(par->value != NULL);
00104
00105 head->value = par->value;
00106 head->next = NULL;
00107 par = par->next;
00108 tail = appendIntList(head, par);
00109
00110 while (head)
00111 {
00112
00113 len = bit_length(((ptr_definition )head->value)->code);
00114 if (!flags[len])
00115 {
00116
00117
00118 if (!((ptr_definition )head->value == top) &&
00119 !((ptr_definition )head->value == built_in) &&
00120 (sub_CodeType(pattern,((ptr_definition)head->value)->code)))
00121 {
00122 or_codes(ans, ((ptr_definition)head->value)->code);
00123
00124
00125 found++;
00126
00127 mark_ancestors((ptr_definition)head->value,flags);
00128 }
00129 else
00130 tail = appendIntList(tail,
00131 ((ptr_definition )head->value)->parents);
00132 flags[len] = 1;
00133 }
00134 head = head->next;
00135 }
00136 return found;
00137 }
00138
00139
00140
00141
00142
00143
00144 static ptr_int_list makeUnitList(x)
00145 ptr_definition x;
00146 {
00147 ptr_int_list ans;
00148
00149 ans = STACK_ALLOC(int_list);
00150 ans->value = (GENERIC )x;
00151 ans->next = NULL;
00152 return ans;
00153 }
00154
00155
00156
00157
00158
00159
00160
00161
00162 ptr_int_list lub(a,b,pp)
00163 ptr_psi_term a;
00164 ptr_psi_term b;
00165 ptr_psi_term *pp;
00166 {
00167 extern long type_count;
00168 ptr_definition ta;
00169 ptr_definition tb;
00170 long *flags;
00171
00172
00173 ptr_int_list ans;
00174 ptr_int_list pattern;
00175 long found;
00176
00177 ta = a->type;
00178 tb = b->type;
00179
00180
00181
00182 if (isValue(a) && isValue(b) && sub_type(ta,tb) && sub_type(tb,ta))
00183 {
00184
00185
00186
00187 if (isSubTypeValue(a, b))
00188 {
00189
00190
00191
00192
00193 *pp = a;
00194 return NULL;
00195 }
00196 }
00197
00198 if (sub_type(ta, tb)) return makeUnitList(tb);
00199 if (sub_type(tb, ta)) return makeUnitList(ta);
00200
00201
00202
00203
00204
00205
00206
00207 pattern = copyTypeCode(ta->code);
00208 or_codes(pattern, tb->code);
00209 ans = copyTypeCode(pattern);
00210
00211
00212
00213 flags = (long *)stack_alloc(sizeof(unsigned long) * type_count);
00214 memset(flags, 0, sizeof(unsigned long) * type_count);
00215
00216
00217
00218 found = bfs(ta, ans, pattern, flags);
00219 found += bfs(tb, ans, pattern, flags);
00220
00221 if (found)
00222 ans = decode(ans);
00223 else
00224 ans = makeUnitList(top);
00225
00226 return ans;
00227 }
00228
00229