1 ///////////////////////////////////////////////////////////////////////////////
2 // This file is generated automatically using Prop (version 2.3.6),
3 // last updated on Nov 2, 1999.
4 // The original source file is "pat.pcc".
5 ///////////////////////////////////////////////////////////////////////////////
8 ///////////////////////////////////////////////////////////////////////////////
10 // This file implements the analysis routines for patterns and match
11 // decision trees. These are used for mode analysis and determinism
12 // analysis for logic clauses compilation.
14 ///////////////////////////////////////////////////////////////////////////////
19 ///////////////////////////////////////////////////////////////////////////////
21 // Convert a pattern into an unifier if the constructor is part of
24 ///////////////////////////////////////////////////////////////////////////////
25 Pat
mkunifier (Cons cons
, Pat pat
, Pat transformed_pat
)
32 switch (cons
->alg_ty
->tag__
) {
33 case a_Ty::tag_TYCONty
: {
34 if (boxed(((Ty_TYCONty
*)cons
->alg_ty
)->_1
)) {
35 switch (((Ty_TYCONty
*)cons
->alg_ty
)->_1
->tag__
) {
36 case a_TyCon::tag_DATATYPEtycon
: {
39 (((TyCon_DATATYPEtycon
*)((Ty_TYCONty
*)cons
->alg_ty
)->_1
)->qualifiers
& QUALunifiable
)
44 Cons unifier_cons
= ((TyCon_DATATYPEtycon
*)((Ty_TYCONty
*)cons
->alg_ty
)->_1
)->terms
[((TyCon_DATATYPEtycon
*)((Ty_TYCONty
*)cons
->alg_ty
)->_1
)->unit
];
45 Bool mode_save
= write_mode
;
47 Pat new_p
= LOGICALpat(ORpat
,transformed_pat
,
48 UNIFYpat(APPpat(CONSpat(unifier_cons
),WILDpat()),
50 write_mode
= mode_save
;
62 default: { goto L1
; } break;
66 default: { goto L1
; } break;
76 ///////////////////////////////////////////////////////////////////////////////
78 // Convert a simple pattern into an unifier.
80 ///////////////////////////////////////////////////////////////////////////////
81 Pat
unifier_of (Pat pat
)
89 case a_Pat::tag_CONSpat
: {
91 new_p
= mkunifier(((Pat_CONSpat
*)pat
)->CONSpat
,pat
,pat
);
94 case a_Pat::tag_APPpat
: {
95 if (((Pat_APPpat
*)pat
)->_1
) {
96 switch (((Pat_APPpat
*)pat
)->_1
->tag__
) {
97 case a_Pat::tag_CONSpat
: {
99 new_p
= mkunifier(((Pat_CONSpat
*)((Pat_APPpat
*)pat
)->_1
)->CONSpat
,pat
,APPpat(((Pat_APPpat
*)pat
)->_1
,unifier_of(((Pat_APPpat
*)pat
)->_2
)));
105 bug ("%Lunsupported unifier: %p", pat
);
111 case a_Pat::tag_TYPEDpat
: {
113 new_p
= TYPEDpat(unifier_of(((Pat_TYPEDpat
*)pat
)->_1
),((Pat_TYPEDpat
*)pat
)->_2
);
116 case a_Pat::tag_ASpat
: {
118 new_p
= ASpat(((Pat_ASpat
*)pat
)->_1
,unifier_of(((Pat_ASpat
*)pat
)->_2
),((Pat_ASpat
*)pat
)->_3
,((Pat_ASpat
*)pat
)->_4
);
121 case a_Pat::tag_ARRAYpat
: {
123 new_p
= ARRAYpat(unifier_of(((Pat_ARRAYpat
*)pat
)->_1
),((Pat_ARRAYpat
*)pat
)->_2
);
126 case a_Pat::tag_TUPLEpat
: {
128 new_p
= TUPLEpat(unifier_of(((Pat_TUPLEpat
*)pat
)->TUPLEpat
));
131 case a_Pat::tag_EXTUPLEpat
: {
133 new_p
= EXTUPLEpat(unifier_of(((Pat_EXTUPLEpat
*)pat
)->EXTUPLEpat
));
136 case a_Pat::tag_RECORDpat
: {
138 new_p
= RECORDpat(unifier_of(((Pat_RECORDpat
*)pat
)->_1
),((Pat_RECORDpat
*)pat
)->_2
);
141 case a_Pat::tag_LISTpat
: {
146 LISTpat(((Pat_LISTpat
*)pat
)->cons
, ((Pat_LISTpat
*)pat
)->nil
, unifier_of(((Pat_LISTpat
*)pat
)->head
), unifier_of(((Pat_LISTpat
*)pat
)->tail
))
153 case a_Pat::tag_VECTORpat
: {
158 VECTORpat(((Pat_VECTORpat
*)pat
)->cons
, unifier_of(((Pat_VECTORpat
*)pat
)->len
), unifier_of(((Pat_VECTORpat
*)pat
)->array
), unifier_of(((Pat_VECTORpat
*)pat
)->elements
), ((Pat_VECTORpat
*)pat
)->head_flex
, ((Pat_VECTORpat
*)pat
)->tail_flex
)
165 case a_Pat::tag_GUARDpat
: {
167 new_p
= GUARDpat(unifier_of(((Pat_GUARDpat
*)pat
)->_1
),((Pat_GUARDpat
*)pat
)->_2
);
170 case a_Pat::tag_LOGICALpat
: {
172 new_p
= LOGICALpat(((Pat_LOGICALpat
*)pat
)->_1
,unifier_of(((Pat_LOGICALpat
*)pat
)->_2
),unifier_of(((Pat_LOGICALpat
*)pat
)->_3
));
175 case a_Pat::tag_MARKEDpat
: {
177 new_p
= MARKEDpat(((Pat_MARKEDpat
*)pat
)->_1
, unifier_of(((Pat_MARKEDpat
*)pat
)->_2
));
180 case a_Pat::tag_WILDpat
:
181 case a_Pat::tag_IDpat
:
182 case a_Pat::tag_LITERALpat
:
183 case a_Pat::tag_CONTEXTpat
:
184 case a_Pat::tag_LEXEMEpat
: {
186 default: { goto L2
; } break;
193 if (new_p
!= pat
&& boxed(pat
) && boxed(new_p
))
194 { new_p
->selector
= pat
->selector
;
200 ///////////////////////////////////////////////////////////////////////////////
202 // Convert a simple pattern list into an unifier list.
204 ///////////////////////////////////////////////////////////////////////////////
205 Pats
unifier_of (Pats pats
)
215 list_1_(unifier_of(pats
->_1
),unifier_of(pats
->_2
))
237 ///////////////////////////////////////////////////////////////////////////////
239 // Convert a simple labeled pattern list into an labeled unifier list.
241 ///////////////////////////////////////////////////////////////////////////////
242 LabPats
unifier_of (LabPats pats
)
250 lab_pat
.label
= pats
->_1
.label
;
251 lab_pat
.pat
= unifier_of(pats
->_1
.pat
);
255 list_1_(lab_pat
,unifier_of(pats
->_2
))
277 ///////////////////////////////////////////////////////////////////////////////
279 // Check whether pattern a subsumes b, i.e. more general.
281 ///////////////////////////////////////////////////////////////////////////////
282 Bool
subsumes (Pat a
, Pat b
, Bool v
)
289 case a_Pat::tag_CONSpat
: {
292 case a_Pat::tag_CONSpat
: {
294 return ((Pat_CONSpat
*)a
)->CONSpat
== ((Pat_CONSpat
*)b
)->CONSpat
;
297 case a_Pat::tag_TYPEDpat
: {
300 return subsumes(a
,((Pat_TYPEDpat
*)b
)->_1
,v
);
303 case a_Pat::tag_ASpat
: {
306 return subsumes(a
,((Pat_ASpat
*)b
)->_2
,v
);
318 case a_Pat::tag_APPpat
: {
321 case a_Pat::tag_APPpat
: {
323 return subsumes(((Pat_APPpat
*)a
)->_1
,((Pat_APPpat
*)b
)->_1
,v
) && subsumes(((Pat_APPpat
*)a
)->_2
,((Pat_APPpat
*)b
)->_2
,v
);
326 case a_Pat::tag_TYPEDpat
: { goto L4
; } break;
327 case a_Pat::tag_ASpat
: { goto L5
; } break;
328 default: { goto L6
; } break;
332 case a_Pat::tag_TYPEDpat
: {
335 case a_Pat::tag_ASpat
: { goto L5
; } break;
339 return subsumes(((Pat_TYPEDpat
*)a
)->_1
,b
,v
);
345 case a_Pat::tag_ASpat
: {
347 return subsumes(((Pat_ASpat
*)a
)->_2
,b
,v
);
350 case a_Pat::tag_LITERALpat
: {
353 case a_Pat::tag_TYPEDpat
: { goto L4
; } break;
354 case a_Pat::tag_ASpat
: { goto L5
; } break;
355 case a_Pat::tag_LITERALpat
: {
357 return literal_equal(((Pat_LITERALpat
*)a
)->LITERALpat
,((Pat_LITERALpat
*)b
)->LITERALpat
);
360 default: { goto L6
; } break;
364 case a_Pat::tag_TUPLEpat
: {
367 case a_Pat::tag_TYPEDpat
: { goto L4
; } break;
368 case a_Pat::tag_ASpat
: { goto L5
; } break;
369 case a_Pat::tag_TUPLEpat
: {
371 return subsumes(((Pat_TUPLEpat
*)a
)->TUPLEpat
,((Pat_TUPLEpat
*)b
)->TUPLEpat
,v
);
374 default: { goto L6
; } break;
378 case a_Pat::tag_EXTUPLEpat
: {
381 case a_Pat::tag_TYPEDpat
: { goto L4
; } break;
382 case a_Pat::tag_ASpat
: { goto L5
; } break;
383 case a_Pat::tag_EXTUPLEpat
: {
385 return subsumes(((Pat_EXTUPLEpat
*)a
)->EXTUPLEpat
,((Pat_EXTUPLEpat
*)b
)->EXTUPLEpat
,v
);
388 default: { goto L6
; } break;
392 case a_Pat::tag_GUARDpat
: {
395 case a_Pat::tag_TYPEDpat
: { goto L4
; } break;
396 case a_Pat::tag_ASpat
: { goto L5
; } break;
397 case a_Pat::tag_GUARDpat
: {
399 return subsumes(((Pat_GUARDpat
*)a
)->_1
,((Pat_GUARDpat
*)b
)->_1
,v
) && equal(((Pat_GUARDpat
*)a
)->_2
,((Pat_GUARDpat
*)b
)->_2
);
402 default: { goto L6
; } break;
406 case a_Pat::tag_LOGICALpat
: {
409 case a_Pat::tag_TYPEDpat
: { goto L4
; } break;
410 case a_Pat::tag_ASpat
: { goto L5
; } break;
413 switch (((Pat_LOGICALpat
*)a
)->_1
) {
417 return subsumes(((Pat_LOGICALpat
*)a
)->_2
,b
,v
) && subsumes(((Pat_LOGICALpat
*)a
)->_3
,b
,v
);
420 default: { goto L6
; } break;
426 case a_Pat::tag_BACKEDGEpat
: {
428 return subsumes(((Pat_BACKEDGEpat
*)a
)->_3
,b
,v
);
431 case a_Pat::tag_WILDpat
:
432 case a_Pat::tag_IDpat
: {
441 case a_Pat::tag_TYPEDpat
: { goto L4
; } break;
442 case a_Pat::tag_ASpat
: { goto L5
; } break;
443 default: { goto L6
; } break;
455 ///////////////////////////////////////////////////////////////////////////////
457 // Checks whether list a subsumes list b. Subsumption is computed
460 ///////////////////////////////////////////////////////////////////////////////
461 Bool
subsumes (Pats a
, Pats b
, Bool v
)
469 return subsumes(a
->_1
,b
->_1
,v
) && subsumes(a
->_2
,b
->_2
,v
);
478 if (b
) { goto L11
; } else {
490 ///////////////////////////////////////////////////////////////////////////////
492 // Computes the subsumption info for two labeled pat lists.
494 ///////////////////////////////////////////////////////////////////////////////
495 Bool
subsumes (LabPats
, LabPats
, Bool verbose
)
500 ------------------------------- Statistics -------------------------------
501 Merge matching rules = yes
502 Number of DFA nodes merged = 751
503 Number of ifs generated = 21
504 Number of switches generated = 15
505 Number of labels = 11
507 Adaptive matching = enabled
508 Fast string matching = disabled
509 Inline downcasts = enabled
510 --------------------------------------------------------------------------