1 /* T Y P E E Q U I V A L E N C E */
3 /* Routines for testing type equivalence & type compatibility.
19 TstTypeEquiv(tp1, tp2)
20 register struct type *tp1, *tp2;
22 /* test if two types are equivalent.
24 return tp1 == tp2 || tp1 == error_type || tp2 == error_type;
29 register struct type *tp;
31 /* string = packed array[1..ub] of char and ub > 1 */
32 if( tp->tp_fund & T_STRINGCONST ) return tp->tp_psize;
34 if( IsConformantArray(tp) ) return 0;
36 if( tp->tp_fund & T_ARRAY && IsPacked(tp) &&
37 tp->arr_elem == char_type ) {
40 if( BaseType(IndexType(tp)) != int_type ) return 0;
41 getbounds(IndexType(tp), &lb, &ub);
42 return (lb == 1 && ub > 1) ? ub : (arith) 0;
48 TstStrCompat(tp1, tp2)
49 register struct type *tp1, *tp2;
51 /* test if two types are compatible string-types.
59 if( !ub1 || !ub2 ) return 0;
66 register struct type *tp1, *tp2;
68 /* test if two types are compatible. ISO 6.4.5
72 if( TstTypeEquiv(tp1, tp2) ) return 1;
75 if( TstStrCompat(tp1, tp2) ) return 1;
77 /* type of NIL is compatible with every pointertype */
78 if( tp1->tp_fund & T_POINTER && tp2->tp_fund & T_POINTER )
79 return tp1 == tp2 || tp1 == nil_type || tp2 == nil_type;
82 /* if both types are sets then both must be packed or not */
83 if( tp1->tp_fund & T_SET && tp2->tp_fund & T_SET ) {
84 if( tp1 == emptyset_type || tp2 == emptyset_type )
86 if( IsPacked(tp1) != IsPacked(tp2) )
88 if( TstCompat(ElementType(tp1), ElementType(tp2)) ) {
90 if( ElementType(tp1) != ElementType(tp2) )
91 warning("base-types of sets not equal");
98 /* no clause, just check for longs and ints */
99 /* BaseType is used in case of array indexing */
100 if ((BaseType(tp1) == int_type && tp2 == long_type) ||
101 (tp1 == long_type && BaseType(tp2) == int_type))
113 TstAssCompat(tp1, tp2)
114 register struct type *tp1, *tp2;
116 /* test if two types are assignment compatible. ISO 6.4.6
119 /* clauses a, c, d and e */
120 if( TstCompat(tp1, tp2) )
121 return !(tp1->tp_flags & T_HASFILE);
124 if( tp1 == real_type )
125 return BaseType(tp2) == int_type || BaseType(tp2) == long_type;
131 TstParEquiv(tp1, tp2)
132 register struct type *tp1, *tp2;
134 /* Test if two parameter types are equivalent. ISO 6.6.3.6
138 TstTypeEquiv(tp1, tp2)
141 IsConformantArray(tp1)
143 IsConformantArray(tp2)
145 IsPacked(tp1) == IsPacked(tp2)
147 TstParEquiv(tp1->arr_elem, tp2->arr_elem)
152 tp1->tp_fund == T_PROCEDURE && tp2->tp_fund == T_PROCEDURE
154 tp1->tp_fund == T_FUNCTION && tp2->tp_fund == T_FUNCTION
157 TstProcEquiv(tp1, tp2)
162 TstProcEquiv(tp1, tp2)
163 register struct type *tp1, *tp2;
165 /* Test if two procedure types are equivalent. ISO 6.6.3.6
167 register struct paramlist *p1, *p2;
169 /* First check if the result types are equivalent
171 if( !TstTypeEquiv(ResultType(tp1), ResultType(tp2)) )
177 /* Now check the parameters
180 if( IsVarParam(p1) != IsVarParam(p2) ||
181 !TstParEquiv(TypeOfParam(p1), TypeOfParam(p2)) ) return 0;
186 /* Here, at least one of the parameterlists is exhausted.
187 Check that they are both.
193 TstParCompat(formaltype, actualtype, VARflag, nd, new_par_section)
194 register struct type *formaltype, *actualtype;
197 /* Check type compatibility for a parameter in a procedure call.
201 TstTypeEquiv(formaltype, actualtype)
203 ( !VARflag && TstAssCompat(formaltype, actualtype) )
205 ( formaltype->tp_fund == T_FUNCTION
207 actualtype->tp_fund == T_FUNCTION
209 TstProcEquiv(formaltype, actualtype)
212 ( formaltype->tp_fund == T_PROCEDURE
214 actualtype->tp_fund == T_PROCEDURE
216 TstProcEquiv(formaltype, actualtype)
219 ( IsConformantArray(formaltype)
221 TstConform(formaltype, actualtype, new_par_section)
224 if( !VARflag && IsConformantArray(actualtype) ) {
226 "conformant array used as value parameter");
234 TstConform(formaltype, actualtype, new_par_section)
235 register struct type *formaltype, *actualtype;
237 /* Check conformability.
239 DEVIATION FROM STANDARD (ISO 6.6.3.7.2):
240 Allow with value parameters also conformant arrays as actual
241 type.(ISO only with var. parameters)
243 Do as much checking on indextypes as possible.
246 struct type *formalindextp, *actualindextp;
247 arith flb, fub, alb, aub;
248 static struct type *lastactual;
250 if( !new_par_section )
251 /* actualparameters of one conformant-array-specification
254 return TstTypeEquiv(actualtype, lastactual);
256 lastactual = actualtype;
258 if( actualtype->tp_fund == T_STRINGCONST ) {
259 actualindextp = int_type;
261 aub = actualtype->tp_psize;
263 else if( actualtype->tp_fund == T_ARRAY ) {
264 actualindextp = IndexType(actualtype);
265 if( bounded(actualindextp) )
266 getbounds(actualindextp, &alb, &aub);
272 if( IsPacked(actualtype) != IsPacked(formaltype) )
275 formalindextp = IndexType(formaltype);
278 if( !TstCompat(actualindextp, formalindextp) )
282 if( bounded(actualindextp) ||
283 actualindextp->tp_fund == T_STRINGCONST ) {
284 /* test was necessary because the actual type could be confor-
287 if( bounded(formalindextp) ) {
288 getbounds(formalindextp, &flb, &fub);
289 if( alb < flb || aub > fub )
295 if( !IsConformantArray(formaltype->arr_elem) )
296 return TstTypeEquiv(actualtype->arr_elem, formaltype->arr_elem);
298 return TstConform(formaltype->arr_elem, actualtype->arr_elem,