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 "lawgen.pcc".
5 ///////////////////////////////////////////////////////////////////////////////
7 #define PROP_TUPLE2_USED
10 ///////////////////////////////////////////////////////////////////////////////
12 // Module to generate law abbreviations.
14 ///////////////////////////////////////////////////////////////////////////////
22 ///////////////////////////////////////////////////////////////////////////////
26 ///////////////////////////////////////////////////////////////////////////////
27 HashTable
DatatypeCompiler::law_env(string_hash
,string_equal
);
29 ///////////////////////////////////////////////////////////////////////////////
31 // Method to lookup a pattern law.
33 ///////////////////////////////////////////////////////////////////////////////
34 Pat
DatatypeCompiler::lookup_pat (Id id
)
35 { HashTable::Entry
* e
= law_env
.lookup(id
);
36 return e
? (Pat
)e
->v
: NOpat
;
39 ///////////////////////////////////////////////////////////////////////////////
41 // Method to enter a new pattern
43 ///////////////////////////////////////////////////////////////////////////////
44 void DatatypeCompiler::add_law(LawDef law_def
)
50 if (lookup_pat(law_def
->id
) != NOpat
) {
51 error ("%Lduplicated definition of pattern constructor '%s'\n",law_def
->id
);
54 Pat p
= law_def
->guard
!= NOexp
? GUARDpat(p
,law_def
->guard
) : law_def
->pat
;
55 law_env
.insert(law_def
->id
, POLYpat(law_def
->id
, length(law_def
->args
), law_def
->args
, p
, law_def
->guard
,
66 ///////////////////////////////////////////////////////////////////////////////
68 // Function 'invertible' checks whether a pattern is invertible into
69 // a pseudo constructor.
71 ///////////////////////////////////////////////////////////////////////////////
74 Bool
invertible (Pat x_1
);
75 Bool
invertible (a_List
<Pat
> * x_1
);
76 Bool
invertible (a_List
<LabPat
> * x_1
);
77 Bool
invertible (Pat x_1
)
81 case a_Pat::tag_APPpat
: {
82 if (((Pat_APPpat
*)x_1
)->_1
) {
83 switch (((Pat_APPpat
*)x_1
)->_1
->tag__
) {
84 case a_Pat::tag_CONSpat
: {
86 return invertible(((Pat_APPpat
*)x_1
)->_2
);
92 bug("invertible: %p", x_1
); return false;
98 case a_Pat::tag_TYPEDpat
: {
100 return invertible(((Pat_TYPEDpat
*)x_1
)->_1
);
101 #line 61 "lawgen.pcc"
103 case a_Pat::tag_ASpat
: {
104 #line 62 "lawgen.pcc"
105 return invertible(((Pat_ASpat
*)x_1
)->_2
);
106 #line 62 "lawgen.pcc"
108 case a_Pat::tag_CONTEXTpat
: {
109 #line 63 "lawgen.pcc"
110 return invertible(((Pat_CONTEXTpat
*)x_1
)->_2
);
111 #line 63 "lawgen.pcc"
113 case a_Pat::tag_TUPLEpat
: {
114 #line 64 "lawgen.pcc"
115 return invertible(((Pat_TUPLEpat
*)x_1
)->TUPLEpat
);
116 #line 64 "lawgen.pcc"
118 case a_Pat::tag_EXTUPLEpat
: {
119 #line 65 "lawgen.pcc"
120 return invertible(((Pat_EXTUPLEpat
*)x_1
)->EXTUPLEpat
);
121 #line 65 "lawgen.pcc"
123 case a_Pat::tag_RECORDpat
: {
124 #line 66 "lawgen.pcc"
125 return ! ((Pat_RECORDpat
*)x_1
)->_2
&& invertible(((Pat_RECORDpat
*)x_1
)->_1
);
126 #line 66 "lawgen.pcc"
128 case a_Pat::tag_LISTpat
: {
129 #line 70 "lawgen.pcc"
130 return invertible(((Pat_LISTpat
*)x_1
)->head
) && invertible(((Pat_LISTpat
*)x_1
)->tail
);
131 #line 70 "lawgen.pcc"
133 case a_Pat::tag_VECTORpat
: {
134 #line 72 "lawgen.pcc"
135 return ! ((Pat_VECTORpat
*)x_1
)->head_flex
&& ! ((Pat_VECTORpat
*)x_1
)->tail_flex
&&
136 invertible(((Pat_VECTORpat
*)x_1
)->len
) && invertible(((Pat_VECTORpat
*)x_1
)->array
) && invertible(((Pat_VECTORpat
*)x_1
)->elements
);
138 #line 74 "lawgen.pcc"
140 case a_Pat::tag_GUARDpat
: {
141 #line 67 "lawgen.pcc"
142 return invertible(((Pat_GUARDpat
*)x_1
)->_1
);
143 #line 67 "lawgen.pcc"
145 case a_Pat::tag_MARKEDpat
: {
146 #line 68 "lawgen.pcc"
147 return invertible(((Pat_MARKEDpat
*)x_1
)->_2
);
148 #line 68 "lawgen.pcc"
150 case a_Pat::tag_WILDpat
:
151 case a_Pat::tag_ARRAYpat
:
152 case a_Pat::tag_APPENDpat
:
153 case a_Pat::tag_LOGICALpat
: {
154 #line 59 "lawgen.pcc"
156 #line 59 "lawgen.pcc"
158 case a_Pat::tag_INDpat
:
159 case a_Pat::tag_IDpat
:
160 case a_Pat::tag_CONSpat
:
161 case a_Pat::tag_LITERALpat
: {
163 #line 57 "lawgen.pcc"
165 #line 57 "lawgen.pcc"
167 default: { goto L1
; } break;
171 Bool
invertible (a_List
<Pat
> * x_1
)
174 #line 78 "lawgen.pcc"
175 return invertible(x_1
->_1
) && invertible(x_1
->_2
);
176 #line 78 "lawgen.pcc"
178 #line 77 "lawgen.pcc"
180 #line 77 "lawgen.pcc"
183 Bool
invertible (a_List
<LabPat
> * x_1
)
186 #line 81 "lawgen.pcc"
187 return invertible(x_1
->_1
.pat
) && invertible(x_1
->_2
);
188 #line 81 "lawgen.pcc"
190 #line 80 "lawgen.pcc"
192 #line 80 "lawgen.pcc"
195 #line 82 "lawgen.pcc"
196 #line 82 "lawgen.pcc"
199 ///////////////////////////////////////////////////////////////////////////////
201 // Function to convert a pattern into a variable creation expression.
203 ///////////////////////////////////////////////////////////////////////////////
204 Exp
mkvariable (Pat p
)
206 #line 90 "lawgen.pcc"
207 #line 96 "lawgen.pcc"
209 Ty _V1
= deref_all(p
->ty
);
211 switch (_V1
->tag__
) {
212 case a_Ty::tag_TYCONty
: {
213 if (boxed(((Ty_TYCONty
*)_V1
)->_1
)) {
214 switch (((Ty_TYCONty
*)_V1
)->_1
->tag__
) {
215 case a_TyCon::tag_DATATYPEtycon
: {
217 #line 92 "lawgen.pcc"
218 (((TyCon_DATATYPEtycon
*)((Ty_TYCONty
*)_V1
)->_1
)->qualifiers
& QUALunifiable
)
219 #line 92 "lawgen.pcc"
222 #line 93 "lawgen.pcc"
223 return APPexp(IDexp(((TyCon_DATATYPEtycon
*)((Ty_TYCONty
*)_V1
)->_1
)->terms
[((TyCon_DATATYPEtycon
*)((Ty_TYCONty
*)_V1
)->_1
)->unit
]->name
),TUPLEexp(
224 #line 93 "lawgen.pcc"
225 #line 93 "lawgen.pcc"
227 #line 93 "lawgen.pcc"
228 #line 93 "lawgen.pcc"
230 #line 93 "lawgen.pcc"
234 #line 94 "lawgen.pcc"
235 error("%L%p with type %T is not unifiable\n", p
, p
->ty
);
238 #line 96 "lawgen.pcc"
241 default: { goto L3
; } break;
245 default: { goto L3
; } break;
249 #line 97 "lawgen.pcc"
250 #line 97 "lawgen.pcc"
254 ///////////////////////////////////////////////////////////////////////////////
256 // Function 'pat2exp' converts an invertible pattern into a
257 // constructor expression. Also extracts the bound variable bindings
260 ///////////////////////////////////////////////////////////////////////////////
262 #line 107 "lawgen.pcc"
263 a_List
<Tuple2
<Id
, Ty
> > *
264 #line 107 "lawgen.pcc"
266 #line 107 "lawgen.pcc"
268 #line 107 "lawgen.pcc"
269 #line 107 "lawgen.pcc"
271 static Exps actual_args
=
272 #line 108 "lawgen.pcc"
273 #line 108 "lawgen.pcc"
275 #line 108 "lawgen.pcc"
276 #line 108 "lawgen.pcc"
278 static Bool application_error
= false;
279 Bool write_mode
= false;
281 #line 112 "lawgen.pcc"
282 #line 173 "lawgen.pcc"
283 Exp
pat2exp (Pat x_1
);
284 Exps
pat2exp (a_List
<Pat
> * x_1
);
285 LabExps
pat2exp (a_List
<LabPat
> * x_1
);
286 Exp
pat2constructor (Pat x_1
);
287 Exp
pat2unifier (Pat x_1
);
288 Exp
pat2exp (Pat x_1
)
291 switch (x_1
->tag__
) {
292 case a_Pat::tag_WILDpat
: {
295 #line 145 "lawgen.pcc"
296 return mkvariable(x_1
);
297 #line 145 "lawgen.pcc"
301 #line 146 "lawgen.pcc"
302 bug("pat2exp: %p", x_1
); return NOexp
;
303 #line 146 "lawgen.pcc"
306 case a_Pat::tag_INDpat
: {
307 if ((actual_args
!= nil_1_
)) {
309 #line 116 "lawgen.pcc"
311 for_each(Exp
, e
, actual_args
)
312 { if (k
== ((Pat_INDpat
*)x_1
)->_2
) return e
;
315 error("%LMissing argument %i in law variable %s\n",((Pat_INDpat
*)x_1
)->_2
,((Pat_INDpat
*)x_1
)->_1
);
316 application_error
= true;
319 #line 124 "lawgen.pcc"
322 #line 126 "lawgen.pcc"
324 #line 126 "lawgen.pcc"
325 #line 126 "lawgen.pcc"
326 list_1_(mkTuple2(((Pat_INDpat
*)x_1
)->_1
,((Pat_INDpat
*)x_1
)->_3
),boundvars
)
327 #line 126 "lawgen.pcc"
328 #line 126 "lawgen.pcc"
330 return IDexp(((Pat_INDpat
*)x_1
)->_1
);
332 #line 128 "lawgen.pcc"
335 case a_Pat::tag_IDpat
: {
336 #line 114 "lawgen.pcc"
337 return write_mode
? mkvariable(x_1
) : IDexp(((Pat_IDpat
*)x_1
)->_1
);
338 #line 114 "lawgen.pcc"
340 case a_Pat::tag_CONSpat
: {
341 if (((Pat_CONSpat
*)x_1
)->CONSpat
) {
342 #line 138 "lawgen.pcc"
343 return IDexp(((Pat_CONSpat
*)x_1
)->CONSpat
->name
);
344 #line 138 "lawgen.pcc"
347 case a_Pat::tag_APPpat
: {
348 if (((Pat_APPpat
*)x_1
)->_1
) {
349 switch (((Pat_APPpat
*)x_1
)->_1
->tag__
) {
350 case a_Pat::tag_CONSpat
: {
351 #line 139 "lawgen.pcc"
352 return CONSexp(((Pat_CONSpat
*)((Pat_APPpat
*)x_1
)->_1
)->CONSpat
,
353 #line 139 "lawgen.pcc"
354 #line 139 "lawgen.pcc"
356 #line 139 "lawgen.pcc"
357 #line 139 "lawgen.pcc"
358 ,pat2exp(((Pat_APPpat
*)x_1
)->_2
));
359 #line 139 "lawgen.pcc"
361 default: { goto L4
; } break;
365 case a_Pat::tag_TYPEDpat
: {
366 #line 130 "lawgen.pcc"
367 return pat2exp(((Pat_TYPEDpat
*)x_1
)->_1
);
368 #line 130 "lawgen.pcc"
370 case a_Pat::tag_ASpat
: {
371 #line 131 "lawgen.pcc"
372 return pat2exp(((Pat_ASpat
*)x_1
)->_2
);
373 #line 131 "lawgen.pcc"
375 case a_Pat::tag_LITERALpat
: {
376 #line 129 "lawgen.pcc"
377 return LITERALexp(((Pat_LITERALpat
*)x_1
)->LITERALpat
);
378 #line 129 "lawgen.pcc"
380 case a_Pat::tag_CONTEXTpat
: {
381 #line 132 "lawgen.pcc"
382 return pat2exp(((Pat_CONTEXTpat
*)x_1
)->_2
);
383 #line 132 "lawgen.pcc"
385 case a_Pat::tag_TUPLEpat
: {
386 #line 133 "lawgen.pcc"
387 return TUPLEexp(pat2exp(((Pat_TUPLEpat
*)x_1
)->TUPLEpat
));
388 #line 133 "lawgen.pcc"
390 case a_Pat::tag_EXTUPLEpat
: {
391 #line 134 "lawgen.pcc"
392 return EXTUPLEexp(pat2exp(((Pat_EXTUPLEpat
*)x_1
)->EXTUPLEpat
));
393 #line 134 "lawgen.pcc"
395 case a_Pat::tag_RECORDpat
: {
396 #line 135 "lawgen.pcc"
397 return RECORDexp(pat2exp(((Pat_RECORDpat
*)x_1
)->_1
));
398 #line 135 "lawgen.pcc"
400 case a_Pat::tag_LISTpat
: {
401 #line 141 "lawgen.pcc"
402 return LISTexp(((Pat_LISTpat
*)x_1
)->cons
,((Pat_LISTpat
*)x_1
)->nil
,pat2exp(((Pat_LISTpat
*)x_1
)->head
),pat2exp(((Pat_LISTpat
*)x_1
)->tail
));
403 #line 141 "lawgen.pcc"
405 case a_Pat::tag_VECTORpat
: {
406 #line 143 "lawgen.pcc"
407 return VECTORexp(((Pat_VECTORpat
*)x_1
)->cons
,pat2exp(((Pat_VECTORpat
*)x_1
)->elements
));
408 #line 143 "lawgen.pcc"
410 case a_Pat::tag_GUARDpat
: {
411 #line 136 "lawgen.pcc"
412 return pat2exp(((Pat_GUARDpat
*)x_1
)->_1
);
413 #line 136 "lawgen.pcc"
415 case a_Pat::tag_MARKEDpat
: {
416 #line 137 "lawgen.pcc"
417 return pat2exp(((Pat_MARKEDpat
*)x_1
)->_2
);
418 #line 137 "lawgen.pcc"
420 default: { goto L4
; } break;
423 #line 112 "lawgen.pcc"
425 #line 112 "lawgen.pcc"
428 Exps
pat2exp (a_List
<Pat
> * x_1
)
431 #line 149 "lawgen.pcc"
433 #line 149 "lawgen.pcc"
434 #line 149 "lawgen.pcc"
435 list_1_(pat2exp(x_1
->_1
),pat2exp(x_1
->_2
))
436 #line 149 "lawgen.pcc"
437 #line 149 "lawgen.pcc"
439 #line 149 "lawgen.pcc"
441 #line 148 "lawgen.pcc"
443 #line 148 "lawgen.pcc"
444 #line 148 "lawgen.pcc"
446 #line 148 "lawgen.pcc"
447 #line 148 "lawgen.pcc"
449 #line 148 "lawgen.pcc"
452 LabExps
pat2exp (a_List
<LabPat
> * x_1
)
455 #line 152 "lawgen.pcc"
457 labexp
.label
= x_1
->_1
.label
;
458 labexp
.exp
= pat2exp(x_1
->_1
.pat
);
460 #line 155 "lawgen.pcc"
461 #line 155 "lawgen.pcc"
462 list_1_(labexp
,pat2exp(x_1
->_2
))
463 #line 155 "lawgen.pcc"
464 #line 155 "lawgen.pcc"
467 #line 156 "lawgen.pcc"
469 #line 151 "lawgen.pcc"
471 #line 151 "lawgen.pcc"
472 #line 151 "lawgen.pcc"
474 #line 151 "lawgen.pcc"
475 #line 151 "lawgen.pcc"
477 #line 151 "lawgen.pcc"
480 Exp
pat2constructor (Pat x_1
)
482 #line 159 "lawgen.pcc"
483 Bool mode_save
= write_mode
;
485 Exp e
= pat2exp(x_1
);
486 write_mode
= mode_save
;
489 #line 164 "lawgen.pcc"
491 Exp
pat2unifier (Pat x_1
)
493 #line 167 "lawgen.pcc"
494 Bool mode_save
= write_mode
;
496 Exp e
= pat2exp(x_1
);
497 write_mode
= mode_save
;
500 #line 172 "lawgen.pcc"
502 #line 173 "lawgen.pcc"
503 #line 173 "lawgen.pcc"
506 ///////////////////////////////////////////////////////////////////////////////
508 // Method to lookup a pattern law.
510 ///////////////////////////////////////////////////////////////////////////////
511 Exp
DatatypeCompiler::lookup_law (Id id
, Exps args
)
512 { Pat pat
= lookup_pat(id
);
514 #line 182 "lawgen.pcc"
515 #line 204 "lawgen.pcc"
518 switch (pat
->tag__
) {
519 case a_Pat::tag_POLYpat
: {
521 #line 183 "lawgen.pcc"
522 (((Pat_POLYpat
*)pat
)->_6
== true)
523 #line 183 "lawgen.pcc"
526 #line 184 "lawgen.pcc"
527 { if (invertible(((Pat_POLYpat
*)pat
)->_4
) && ((Pat_POLYpat
*)pat
)->_5
== NOexp
)
528 { actual_args
= args
;
529 application_error
= false;
530 if (((Pat_POLYpat
*)pat
)->_2
!= length(args
))
531 { error("%Larity mismatch between law %p and arguments %f\n",
532 ((Pat_POLYpat
*)pat
)->_4
, TUPLEexp(args
));
535 Exp exp
= pat2exp(((Pat_POLYpat
*)pat
)->_4
);
537 #line 193 "lawgen.pcc"
538 #line 193 "lawgen.pcc"
540 #line 193 "lawgen.pcc"
541 #line 193 "lawgen.pcc"
543 if (application_error
)
544 error("%Lcannot apply law %p with arguments %f\n",
545 ((Pat_POLYpat
*)pat
)->_4
, TUPLEexp(args
));
548 { error ("%Llaw %s(...) = %p is not invertible\n",((Pat_POLYpat
*)pat
)->_1
,((Pat_POLYpat
*)pat
)->_4
);
552 #line 202 "lawgen.pcc"
557 default: { goto L5
; } break;
561 #line 204 "lawgen.pcc"
562 #line 204 "lawgen.pcc"
567 ///////////////////////////////////////////////////////////////////////////////
569 // Method to generate pattern law definitions
571 ///////////////////////////////////////////////////////////////////////////////
572 void DatatypeCompiler::gen_law_defs (LawDefs law_defs
)
574 for_each (LawDef
, l
, law_defs
)
576 #line 216 "lawgen.pcc"
577 #line 234 "lawgen.pcc"
579 #line 218 "lawgen.pcc"
582 // infer the type of the pattern.
583 l
->ty
= type_of(l
->pat
);
585 // If the law is invertible, generate
588 { if (invertible(l
->pat
) && l
->guard
== NOexp
)
590 #line 227 "lawgen.pcc"
591 #line 227 "lawgen.pcc"
593 #line 227 "lawgen.pcc"
594 #line 227 "lawgen.pcc"
596 gen_law_inverse(l
->loc(),l
->id
,l
->args
,pat2constructor(l
->pat
),l
->ty
);
598 #line 229 "lawgen.pcc"
599 #line 229 "lawgen.pcc"
601 #line 229 "lawgen.pcc"
602 #line 229 "lawgen.pcc"
605 { error ("%Llaw %s(...) = %p is not invertible\n",l
->id
,l
->pat
);
609 #line 234 "lawgen.pcc"
611 #line 235 "lawgen.pcc"
612 #line 235 "lawgen.pcc"
617 ///////////////////////////////////////////////////////////////////////////////
619 // Check if type can be a C++ parameter
621 ///////////////////////////////////////////////////////////////////////////////
622 Bool
is_parameter_type (Ty ty
)
624 #line 245 "lawgen.pcc"
625 #line 247 "lawgen.pcc"
629 switch (_V2
->tag__
) {
630 case a_Ty::tag_TYCONty
: {
631 if (boxed(((Ty_TYCONty
*)_V2
)->_1
)) {
632 switch (((Ty_TYCONty
*)_V2
)->_1
->tag__
) {
633 case a_TyCon::tag_RECORDtycon
:
634 case a_TyCon::tag_ARRAYtycon
: {
636 #line 246 "lawgen.pcc"
638 #line 246 "lawgen.pcc"
642 #line 247 "lawgen.pcc"
644 #line 247 "lawgen.pcc"
648 switch ((int)((Ty_TYCONty
*)_V2
)->_1
) {
649 case ((int)TUPLEtycon
): { goto L6
; } break;
650 default: { goto L7
; } break;
654 default: { goto L7
; } break;
658 #line 248 "lawgen.pcc"
659 #line 248 "lawgen.pcc"
664 ///////////////////////////////////////////////////////////////////////////////
666 // Method to generate an inverse for a law definition
668 ///////////////////////////////////////////////////////////////////////////////
669 void DatatypeCompiler::gen_law_inverse
670 (const Loc
* location
, Id id
, Ids args
, Exp exp
, Ty ty
)
671 { // Generate the header name
673 "%^// Definition of law %s"
677 id
, location
->begin_line
, location
->file_name
, ty
, id
);
679 // Generate the parameters
682 #line 269 "lawgen.pcc"
683 #line 295 "lawgen.pcc"
687 #line 271 "lawgen.pcc"
690 #line 272 "lawgen.pcc"
691 a_List
<Tuple2
<Id
, Ty
> > *
692 #line 272 "lawgen.pcc"
695 Bool mode_save
= write_mode
;
698 #line 287 "lawgen.pcc"
702 #line 278 "lawgen.pcc"
703 if (bvs
->_1
._1
== args
->_1
)
704 { if (! is_parameter_type(bvs
->_1
._2
))
705 { error("%Llaw '%s': type %T cannot be used in parameter %s\n",
706 id
, bvs
->_1
._2
,bvs
->_1
._1
);
708 found
= true; pr("%t",bvs
->_1
._2
,bvs
->_1
._1
);
710 #line 284 "lawgen.pcc"
711 #line 284 "lawgen.pcc"
713 #line 284 "lawgen.pcc"
714 #line 284 "lawgen.pcc"
719 #line 287 "lawgen.pcc"
724 #line 288 "lawgen.pcc"
725 #line 288 "lawgen.pcc"
728 error("%Llaw '%s': bound variable '%s' is absent in body %e\n",
732 write_mode
= mode_save
;
734 #line 295 "lawgen.pcc"
739 #line 296 "lawgen.pcc"
740 #line 296 "lawgen.pcc"
744 pr(")%^{ return %e; }\n\n", exp
);
746 #line 301 "lawgen.pcc"
748 ------------------------------- Statistics -------------------------------
749 Merge matching rules = yes
750 Number of DFA nodes merged = 141
751 Number of ifs generated = 20
752 Number of switches generated = 10
755 Adaptive matching = enabled
756 Fast string matching = disabled
757 Inline downcasts = enabled
758 --------------------------------------------------------------------------