simple.cc - generated code example
[prop.git] / prop-src / matchcom.cc
blobe23320da262f43991ff44e6c1ba2786a35df63b7
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 "matchcom.pcc".
5 ///////////////////////////////////////////////////////////////////////////////
7 #define PROP_QUARK_USED
8 #include <propdefs.h>
9 ///////////////////////////////////////////////////////////////////////////////
10 // Quark literals
11 ///////////////////////////////////////////////////////////////////////////////
12 static const Quark _m_a_t_c_h_c_o_mco_c_c_Q1("?lexeme");
13 #line 1 "matchcom.pcc"
14 ///////////////////////////////////////////////////////////////////////////////
16 // This file contains the pattern matching compiler of the Prop -> C++
17 // translator. The following methods are implemented:
19 // (i) Variable bindings computation of patterns.
20 // (ii) Translation of patterns into decision trees.
21 // (iii) Merging, transformation and minimization of decision trees/dags.
23 ///////////////////////////////////////////////////////////////////////////////
25 #include <string.h>
26 #include <limits.h>
27 #include <stdlib.h>
28 #include <AD/contain/bitset.h>
29 #include <AD/generic/ordering.h>
30 #include <AD/strings/quark.h>
31 #include <AD/strings/charesc.h>
32 #include "ir.h"
33 #include "ast.h"
34 #include "matchcom.h"
35 #include "patenv.h"
36 #include "hashtab.h"
37 #include "config.h"
38 #include "type.h"
39 #include "options.h"
40 #include "list.h"
42 ///////////////////////////////////////////////////////////////////////////////
44 // Constructor and destructor for class MatchCompiler
46 ///////////////////////////////////////////////////////////////////////////////
47 MatchCompiler:: MatchCompiler()
48 : vars("_X"), labels("L"),
49 merges(0), ifs(0), switches(0), gotos(0), goto_labels(0),
50 current_options(MATCHnone), current_rule(0)
52 MatchCompiler::~MatchCompiler() {}
54 MatchBase::MatchBase() : shared(0), label(0) {}
56 HashTable MatchCompiler::quark_map(string_hash,string_equal);
57 LabelGen MatchCompiler::quark_labels("_Q");
59 ///////////////////////////////////////////////////////////////////////////////
61 // Constructor for MatchRuleInfo
63 ///////////////////////////////////////////////////////////////////////////////
64 MatchRuleInfo::MatchRuleInfo ()
65 : used(false), ty(NOty), rule_number(0), negated(false), rewriting(false),
66 is_chain_rule(false), mode(BOTTOMUP), option(NO_OPTIONS) {}
68 ///////////////////////////////////////////////////////////////////////////////
70 // Flag that makes all selectors refer to the same object.
72 ///////////////////////////////////////////////////////////////////////////////
73 Bool same_selectors = false;
75 ///////////////////////////////////////////////////////////////////////////////
77 // Allocation routines
79 ///////////////////////////////////////////////////////////////////////////////
80 Literal * MatchCompiler::Literals(int n)
81 { return (Literal *)mem_pool[n * sizeof(Literal)]; }
82 Match * MatchCompiler::Matches(int n)
83 { return (Match *)mem_pool[n * sizeof(Match)]; }
84 static Literal * vec (Literal l)
85 { Literal * L = (Literal *)mem_pool[sizeof(Literal)];
86 L[0] = l;
87 return L;
89 static Match * vec (Match m)
90 { Match * M = (Match *)mem_pool[sizeof(Match)];
91 M[0] = m;
92 return M;
95 ///////////////////////////////////////////////////////////////////////////////
97 // The mapping from quark name to identifiers
99 ///////////////////////////////////////////////////////////////////////////////
100 Id MatchCompiler::quark_name(Id id)
101 { HashTable::Entry * e = quark_map.lookup(id);
102 if (e)
103 { return (Id)e->v;
104 } else
105 { Id name = Quark(options.mangled_file_name, quark_labels.new_label());
106 quark_map.insert((HashTable::Key)id,(HashTable::Value)name);
107 return name;
111 ///////////////////////////////////////////////////////////////////////////////
113 // Reverse the polarity of a pattern.
115 ///////////////////////////////////////////////////////////////////////////////
116 #line 103 "matchcom.pcc"
117 #line 106 "matchcom.pcc"
118 Polarity rev (Polarity x_1);
119 Polarity rev (Polarity x_1)
121 switch (x_1) {
122 case ISpositive: {
123 #line 103 "matchcom.pcc"
124 return ISnegative;
125 #line 104 "matchcom.pcc"
126 } break;
127 case ISnegative: {
128 #line 104 "matchcom.pcc"
129 return ISpositive;
130 #line 105 "matchcom.pcc"
131 } break;
132 default: {
133 #line 105 "matchcom.pcc"
134 return ISneither;
135 #line 106 "matchcom.pcc"
136 } break;
139 #line 106 "matchcom.pcc"
140 #line 106 "matchcom.pcc"
143 ///////////////////////////////////////////////////////////////////////////////
145 // Method to perform substitution on a pattern.
147 ///////////////////////////////////////////////////////////////////////////////
148 Pat subst(Pat pat, Pat env[], Bool copy)
150 #line 114 "matchcom.pcc"
151 #line 147 "matchcom.pcc"
153 for (;;) {
154 if (pat) {
155 switch (pat->tag__) {
156 case a_Pat::tag_INDpat: {
157 if (
158 #line 120 "matchcom.pcc"
159 copy
160 #line 120 "matchcom.pcc"
163 #line 120 "matchcom.pcc"
164 return INDpat(((Pat_INDpat *)pat)->_1,((Pat_INDpat *)pat)->_2,((Pat_INDpat *)pat)->_3);
165 #line 120 "matchcom.pcc"
166 } else {
168 #line 121 "matchcom.pcc"
169 return subst(env[((Pat_INDpat *)pat)->_2], env, true);
170 #line 121 "matchcom.pcc"
172 } break;
173 case a_Pat::tag_IDpat: {
174 #line 116 "matchcom.pcc"
175 return IDpat(((Pat_IDpat *)pat)->_1,((Pat_IDpat *)pat)->_2,((Pat_IDpat *)pat)->_3);
176 #line 116 "matchcom.pcc"
177 } break;
178 case a_Pat::tag_CONSpat: {
179 #line 118 "matchcom.pcc"
180 return CONSpat(((Pat_CONSpat *)pat)->CONSpat);
181 #line 118 "matchcom.pcc"
182 } break;
183 case a_Pat::tag_APPpat: {
184 #line 122 "matchcom.pcc"
185 return APPpat(subst(((Pat_APPpat *)pat)->_1,env,copy),subst(((Pat_APPpat *)pat)->_2,env,copy));
186 #line 122 "matchcom.pcc"
187 } break;
188 case a_Pat::tag_TYPEDpat: {
189 #line 123 "matchcom.pcc"
190 return TYPEDpat(subst(((Pat_TYPEDpat *)pat)->_1,env,copy),((Pat_TYPEDpat *)pat)->_2);
191 #line 123 "matchcom.pcc"
192 } break;
193 case a_Pat::tag_ASpat: {
194 #line 124 "matchcom.pcc"
195 return ASpat(((Pat_ASpat *)pat)->_1,subst(((Pat_ASpat *)pat)->_2,env,copy),((Pat_ASpat *)pat)->_3,((Pat_ASpat *)pat)->_4);
196 #line 124 "matchcom.pcc"
197 } break;
198 case a_Pat::tag_LITERALpat: {
199 #line 117 "matchcom.pcc"
200 return LITERALpat(((Pat_LITERALpat *)pat)->LITERALpat);
201 #line 117 "matchcom.pcc"
202 } break;
203 case a_Pat::tag_CONTEXTpat: {
204 #line 119 "matchcom.pcc"
205 return CONTEXTpat(((Pat_CONTEXTpat *)pat)->_1,subst(((Pat_CONTEXTpat *)pat)->_2,env,copy));
206 #line 119 "matchcom.pcc"
207 } break;
208 case a_Pat::tag_ARRAYpat: {
209 #line 127 "matchcom.pcc"
210 return ARRAYpat(subst(((Pat_ARRAYpat *)pat)->_1,env,copy),((Pat_ARRAYpat *)pat)->_2);
211 #line 127 "matchcom.pcc"
212 } break;
213 case a_Pat::tag_TUPLEpat: {
214 #line 125 "matchcom.pcc"
215 return TUPLEpat(subst(((Pat_TUPLEpat *)pat)->TUPLEpat,env,copy));
216 #line 125 "matchcom.pcc"
217 } break;
218 case a_Pat::tag_EXTUPLEpat: {
219 #line 126 "matchcom.pcc"
220 return EXTUPLEpat(subst(((Pat_EXTUPLEpat *)pat)->EXTUPLEpat,env,copy));
221 #line 126 "matchcom.pcc"
222 } break;
223 case a_Pat::tag_RECORDpat: {
224 #line 138 "matchcom.pcc"
225 return RECORDpat(subst(((Pat_RECORDpat *)pat)->_1,env,copy),((Pat_RECORDpat *)pat)->_2);
226 #line 138 "matchcom.pcc"
227 } break;
228 case a_Pat::tag_LISTpat: {
229 #line 139 "matchcom.pcc"
230 return
231 #line 139 "matchcom.pcc"
232 #line 139 "matchcom.pcc"
233 LISTpat(((Pat_LISTpat *)pat)->cons, ((Pat_LISTpat *)pat)->nil, subst(((Pat_LISTpat *)pat)->head,env,copy), subst(((Pat_LISTpat *)pat)->tail,env,copy))
234 #line 142 "matchcom.pcc"
235 #line 142 "matchcom.pcc"
238 #line 143 "matchcom.pcc"
239 } break;
240 case a_Pat::tag_VECTORpat: {
241 #line 129 "matchcom.pcc"
242 return
243 #line 129 "matchcom.pcc"
244 #line 129 "matchcom.pcc"
245 VECTORpat(((Pat_VECTORpat *)pat)->cons, subst(((Pat_VECTORpat *)pat)->len,env,copy), subst(((Pat_VECTORpat *)pat)->array,env,copy), subst(((Pat_VECTORpat *)pat)->elements,env,copy), ((Pat_VECTORpat *)pat)->head_flex, ((Pat_VECTORpat *)pat)->tail_flex)
246 #line 136 "matchcom.pcc"
247 #line 136 "matchcom.pcc"
250 #line 137 "matchcom.pcc"
251 } break;
252 case a_Pat::tag_GUARDpat: {
253 #line 146 "matchcom.pcc"
254 return GUARDpat(subst(((Pat_GUARDpat *)pat)->_1,env,copy),((Pat_GUARDpat *)pat)->_2);
255 #line 146 "matchcom.pcc"
256 } break;
257 case a_Pat::tag_LOGICALpat: {
258 #line 144 "matchcom.pcc"
259 return LOGICALpat(((Pat_LOGICALpat *)pat)->_1,subst(((Pat_LOGICALpat *)pat)->_2,env,copy),subst(((Pat_LOGICALpat *)pat)->_3,env,copy));
260 #line 144 "matchcom.pcc"
261 } break;
262 case a_Pat::tag_MARKEDpat: {
263 #line 145 "matchcom.pcc"
264 pat = ((Pat_MARKEDpat *)pat)->_2;
265 #line 145 "matchcom.pcc"
266 } break;
267 case a_Pat::tag_WILDpat:
268 case a_Pat::tag_LEXEMEpat: {
269 L2:;
270 #line 115 "matchcom.pcc"
271 return pat;
272 #line 115 "matchcom.pcc"
273 } break;
274 default: {
275 #line 147 "matchcom.pcc"
276 bug("subst()");
277 #line 147 "matchcom.pcc"
278 } break;
280 } else { goto L2; }
283 #line 148 "matchcom.pcc"
284 #line 148 "matchcom.pcc"
288 ///////////////////////////////////////////////////////////////////////////////
290 // Method to perform substitution on a pattern list.
292 ///////////////////////////////////////////////////////////////////////////////
293 Pats subst(Pats pats, Pat env[], Bool copy)
295 #line 157 "matchcom.pcc"
296 #line 159 "matchcom.pcc"
298 if (pats) {
299 #line 159 "matchcom.pcc"
300 return
301 #line 159 "matchcom.pcc"
302 #line 159 "matchcom.pcc"
303 list_1_(subst(pats->_1,env,copy),subst(pats->_2,env,copy))
304 #line 159 "matchcom.pcc"
305 #line 159 "matchcom.pcc"
307 #line 159 "matchcom.pcc"
308 } else {
309 #line 158 "matchcom.pcc"
310 return
311 #line 158 "matchcom.pcc"
312 #line 158 "matchcom.pcc"
313 nil_1_
314 #line 158 "matchcom.pcc"
315 #line 158 "matchcom.pcc"
317 #line 158 "matchcom.pcc"
320 #line 160 "matchcom.pcc"
321 #line 160 "matchcom.pcc"
325 ///////////////////////////////////////////////////////////////////////////////
327 // Method to perform substitution on a labeled pattern list.
329 ///////////////////////////////////////////////////////////////////////////////
330 LabPats subst(LabPats pats, Pat env[], Bool copy)
332 #line 169 "matchcom.pcc"
333 #line 175 "matchcom.pcc"
335 if (pats) {
336 #line 171 "matchcom.pcc"
337 LabPat l;
338 l.label = pats->_1.label;
339 l.pat = subst(pats->_1.pat,env,copy);
340 return
341 #line 174 "matchcom.pcc"
342 #line 174 "matchcom.pcc"
343 list_1_(l,subst(pats->_2,env,copy))
344 #line 174 "matchcom.pcc"
345 #line 174 "matchcom.pcc"
348 #line 175 "matchcom.pcc"
349 } else {
350 #line 170 "matchcom.pcc"
351 return
352 #line 170 "matchcom.pcc"
353 #line 170 "matchcom.pcc"
354 nil_1_
355 #line 170 "matchcom.pcc"
356 #line 170 "matchcom.pcc"
358 #line 170 "matchcom.pcc"
361 #line 176 "matchcom.pcc"
362 #line 176 "matchcom.pcc"
366 ///////////////////////////////////////////////////////////////////////////////
368 // Pattern application.
370 ///////////////////////////////////////////////////////////////////////////////
371 Pat apply_pat (Pat scheme, Pat arg)
373 #line 185 "matchcom.pcc"
374 #line 198 "matchcom.pcc"
376 if (scheme) {
377 switch (scheme->tag__) {
378 case a_Pat::tag_POLYpat: {
379 if (arg) {
380 switch (arg->tag__) {
381 case a_Pat::tag_TUPLEpat: {
382 if (
383 #line 188 "matchcom.pcc"
384 (length(((Pat_TUPLEpat *)arg)->TUPLEpat) == ((Pat_POLYpat *)scheme)->_2)
385 #line 188 "matchcom.pcc"
388 switch (((Pat_POLYpat *)scheme)->_2) {
389 case 0: {
390 if (arg) {
391 L3:;
392 #line 189 "matchcom.pcc"
393 Pat env[256];
394 int i = 0;
395 for_each (Pat, p, ((Pat_TUPLEpat *)arg)->TUPLEpat) env[i++] = p;
396 return subst(((Pat_POLYpat *)scheme)->_4,env,false);
398 #line 193 "matchcom.pcc"
399 } else {
400 L4:;
401 #line 186 "matchcom.pcc"
402 return subst(((Pat_POLYpat *)scheme)->_4,0,false);
403 #line 186 "matchcom.pcc"
405 } break;
406 case 1: {
407 L5:;
408 #line 187 "matchcom.pcc"
409 return subst(((Pat_POLYpat *)scheme)->_4,&arg,false);
410 #line 187 "matchcom.pcc"
411 } break;
412 default: { goto L3; }
414 } else {
416 L6:;
417 switch (((Pat_POLYpat *)scheme)->_2) {
418 case 0: {
419 L7:;
420 if (arg) {
421 L8:;
422 #line 195 "matchcom.pcc"
423 error ("%Lunable to apply pattern scheme %p\n"
424 "%Lwith argument %p\n", scheme, arg);
425 return NOpat;
427 #line 198 "matchcom.pcc"
428 } else { goto L4; }
429 } break;
430 case 1: { goto L5; } break;
431 default: { goto L8; }
434 } break;
435 default: { goto L6; } break;
437 } else { goto L6; }
438 } break;
439 default: { goto L8; } break;
441 } else { goto L8; }
443 #line 199 "matchcom.pcc"
444 #line 199 "matchcom.pcc"
448 ////////////////////////////////////////////////////////////////////////////////
450 // Substitution on expressions.
452 ///////////////////////////////////////////////////////////////////////////////
453 Exp subst (Exp exp, Exp s[])
455 #line 208 "matchcom.pcc"
456 #line 233 "matchcom.pcc"
458 for (;;) {
459 if (exp) {
460 switch (exp->tag__) {
461 case a_Exp::tag_RELexp: {
462 #line 210 "matchcom.pcc"
463 return s[((Exp_RELexp *)exp)->RELexp];
464 #line 210 "matchcom.pcc"
465 } break;
466 case a_Exp::tag_DOTexp: {
467 #line 209 "matchcom.pcc"
468 return DOTexp(subst(((Exp_DOTexp *)exp)->_1,s),((Exp_DOTexp *)exp)->_2);
469 #line 209 "matchcom.pcc"
470 } break;
471 case a_Exp::tag_SELECTORexp: {
472 #line 211 "matchcom.pcc"
473 return SELECTORexp(subst(((Exp_SELECTORexp *)exp)->_1,s),((Exp_SELECTORexp *)exp)->_2,((Exp_SELECTORexp *)exp)->_3);
474 #line 211 "matchcom.pcc"
475 } break;
476 case a_Exp::tag_DEREFexp: {
477 #line 212 "matchcom.pcc"
478 return DEREFexp(subst(((Exp_DEREFexp *)exp)->DEREFexp,s));
479 #line 212 "matchcom.pcc"
480 } break;
481 case a_Exp::tag_ARROWexp: {
482 #line 213 "matchcom.pcc"
483 return ARROWexp(subst(((Exp_ARROWexp *)exp)->_1,s),((Exp_ARROWexp *)exp)->_2);
484 #line 213 "matchcom.pcc"
485 } break;
486 case a_Exp::tag_INDEXexp: {
487 #line 214 "matchcom.pcc"
488 return INDEXexp(subst(((Exp_INDEXexp *)exp)->_1,s), subst(((Exp_INDEXexp *)exp)->_2,s));
489 #line 214 "matchcom.pcc"
490 } break;
491 case a_Exp::tag_BINOPexp: {
492 #line 215 "matchcom.pcc"
493 return BINOPexp(((Exp_BINOPexp *)exp)->_1,subst(((Exp_BINOPexp *)exp)->_2,s),subst(((Exp_BINOPexp *)exp)->_3,s));
494 #line 215 "matchcom.pcc"
495 } break;
496 case a_Exp::tag_PREFIXexp: {
497 #line 216 "matchcom.pcc"
498 return PREFIXexp(((Exp_PREFIXexp *)exp)->_1,subst(((Exp_PREFIXexp *)exp)->_2,s));
499 #line 216 "matchcom.pcc"
500 } break;
501 case a_Exp::tag_POSTFIXexp: {
502 #line 217 "matchcom.pcc"
503 return POSTFIXexp(((Exp_POSTFIXexp *)exp)->_1,subst(((Exp_POSTFIXexp *)exp)->_2,s));
504 #line 217 "matchcom.pcc"
505 } break;
506 case a_Exp::tag_APPexp: {
507 #line 218 "matchcom.pcc"
508 return APPexp(subst(((Exp_APPexp *)exp)->_1,s), subst(((Exp_APPexp *)exp)->_2,s));
509 #line 218 "matchcom.pcc"
510 } break;
511 case a_Exp::tag_ASSIGNexp: {
512 #line 219 "matchcom.pcc"
513 return ASSIGNexp(subst(((Exp_ASSIGNexp *)exp)->_1,s), subst(((Exp_ASSIGNexp *)exp)->_2,s));
514 #line 219 "matchcom.pcc"
515 } break;
516 case a_Exp::tag_IFexp: {
517 #line 220 "matchcom.pcc"
518 return IFexp(subst(((Exp_IFexp *)exp)->_1,s), subst(((Exp_IFexp *)exp)->_2,s), subst(((Exp_IFexp *)exp)->_3,s));
519 #line 220 "matchcom.pcc"
520 } break;
521 case a_Exp::tag_TUPLEexp: {
522 #line 221 "matchcom.pcc"
523 return TUPLEexp(subst(((Exp_TUPLEexp *)exp)->TUPLEexp,s));
524 #line 221 "matchcom.pcc"
525 } break;
526 case a_Exp::tag_RECORDexp: {
527 #line 222 "matchcom.pcc"
528 return RECORDexp(subst(((Exp_RECORDexp *)exp)->RECORDexp,s));
529 #line 222 "matchcom.pcc"
530 } break;
531 case a_Exp::tag_LISTexp: {
532 #line 224 "matchcom.pcc"
533 return LISTexp(((Exp_LISTexp *)exp)->_1,((Exp_LISTexp *)exp)->_2,subst(((Exp_LISTexp *)exp)->_3,s),subst(((Exp_LISTexp *)exp)->_4,s));
534 #line 224 "matchcom.pcc"
535 } break;
536 case a_Exp::tag_CONSexp: {
537 #line 225 "matchcom.pcc"
538 return CONSexp(((Exp_CONSexp *)exp)->_1,subst(((Exp_CONSexp *)exp)->_2,s),subst(((Exp_CONSexp *)exp)->_3,s));
539 #line 225 "matchcom.pcc"
540 } break;
541 case a_Exp::tag_CASTexp: {
542 #line 226 "matchcom.pcc"
543 return CASTexp(((Exp_CASTexp *)exp)->_1,subst(((Exp_CASTexp *)exp)->_2,s));
544 #line 226 "matchcom.pcc"
545 } break;
546 case a_Exp::tag_EQexp: {
547 #line 227 "matchcom.pcc"
548 return EQexp(((Exp_EQexp *)exp)->_1,subst(((Exp_EQexp *)exp)->_2,s),subst(((Exp_EQexp *)exp)->_3,s));
549 #line 227 "matchcom.pcc"
550 } break;
551 case a_Exp::tag_UNIFYexp: {
552 #line 228 "matchcom.pcc"
553 return UNIFYexp(((Exp_UNIFYexp *)exp)->_1,subst(((Exp_UNIFYexp *)exp)->_2,s),subst(((Exp_UNIFYexp *)exp)->_3,s));
554 #line 228 "matchcom.pcc"
555 } break;
556 case a_Exp::tag_LTexp: {
557 #line 229 "matchcom.pcc"
558 return LTexp(((Exp_LTexp *)exp)->_1,subst(((Exp_LTexp *)exp)->_2,s),subst(((Exp_LTexp *)exp)->_3,s));
559 #line 229 "matchcom.pcc"
560 } break;
561 case a_Exp::tag_HASHexp: {
562 #line 230 "matchcom.pcc"
563 return HASHexp(((Exp_HASHexp *)exp)->_1,subst(((Exp_HASHexp *)exp)->_2,s));
564 #line 230 "matchcom.pcc"
565 } break;
566 case a_Exp::tag_SENDexp: {
567 #line 223 "matchcom.pcc"
568 return SENDexp(((Exp_SENDexp *)exp)->_1,subst(((Exp_SENDexp *)exp)->_2,s));
569 #line 223 "matchcom.pcc"
570 } break;
571 case a_Exp::tag_SETLexp: {
572 #line 231 "matchcom.pcc"
573 return SETLexp(((Exp_SETLexp *)exp)->_1,subst(((Exp_SETLexp *)exp)->_2,s));
574 #line 231 "matchcom.pcc"
575 } break;
576 case a_Exp::tag_MARKEDexp: {
577 #line 232 "matchcom.pcc"
578 exp = ((Exp_MARKEDexp *)exp)->_2;
579 #line 232 "matchcom.pcc"
580 } break;
581 default: {
582 L10:;
583 #line 233 "matchcom.pcc"
584 return exp;
585 #line 233 "matchcom.pcc"
586 } break;
588 } else { goto L10; }
591 #line 234 "matchcom.pcc"
592 #line 234 "matchcom.pcc"
596 ///////////////////////////////////////////////////////////////////////////////
598 // Substitution on expression lists.
600 ///////////////////////////////////////////////////////////////////////////////
601 Exps subst(Exps es, Exp s[])
603 #line 243 "matchcom.pcc"
604 #line 245 "matchcom.pcc"
606 if (es) {
607 #line 245 "matchcom.pcc"
608 return
609 #line 245 "matchcom.pcc"
610 #line 245 "matchcom.pcc"
611 list_1_(subst(es->_1,s),subst(es->_2,s))
612 #line 245 "matchcom.pcc"
613 #line 245 "matchcom.pcc"
615 #line 245 "matchcom.pcc"
616 } else {
617 #line 244 "matchcom.pcc"
618 return
619 #line 244 "matchcom.pcc"
620 #line 244 "matchcom.pcc"
621 nil_1_
622 #line 244 "matchcom.pcc"
623 #line 244 "matchcom.pcc"
625 #line 244 "matchcom.pcc"
628 #line 246 "matchcom.pcc"
629 #line 246 "matchcom.pcc"
633 ///////////////////////////////////////////////////////////////////////////////
635 // Substitution on labeled expression lists.
637 ///////////////////////////////////////////////////////////////////////////////
638 LabExps subst(LabExps es, Exp s[])
640 #line 255 "matchcom.pcc"
641 #line 261 "matchcom.pcc"
643 if (es) {
644 #line 257 "matchcom.pcc"
645 LabExp e;
646 e.label = es->_1.label;
647 e.exp = subst(es->_1.exp,s);
648 return
649 #line 260 "matchcom.pcc"
650 #line 260 "matchcom.pcc"
651 list_1_(e,subst(es->_2,s))
652 #line 260 "matchcom.pcc"
653 #line 260 "matchcom.pcc"
656 #line 261 "matchcom.pcc"
657 } else {
658 #line 256 "matchcom.pcc"
659 return
660 #line 256 "matchcom.pcc"
661 #line 256 "matchcom.pcc"
662 nil_1_
663 #line 256 "matchcom.pcc"
664 #line 256 "matchcom.pcc"
666 #line 256 "matchcom.pcc"
669 #line 262 "matchcom.pcc"
670 #line 262 "matchcom.pcc"
674 ///////////////////////////////////////////////////////////////////////////////
676 // Compute the view selector given the type
678 ///////////////////////////////////////////////////////////////////////////////
679 Exp view_selector_of(Cons cons, Pat pat, Exp e, Ty ty)
680 { Exp selector_exp = default_val(ty);
681 if (selector_exp == NOexp)
682 { error ("%Laccessor is undefined for view pattern: %s %p\n",
683 (cons != NOcons ? cons->name : "???"), pat);
684 return NOexp;
685 } else
686 { return subst(selector_exp,&e);
690 ///////////////////////////////////////////////////////////////////////////////
692 // Decorate selector bindings for a view constructor
694 ///////////////////////////////////////////////////////////////////////////////
695 void decor_view
696 (Cons cons, Pat pat, Exp sel,
697 Polarity polarity, Bool visible, PatternVarEnv& E, int& match_rule)
699 if (boxed(pat)) pat->selector = sel; // annotate selector
701 #line 291 "matchcom.pcc"
702 #line 331 "matchcom.pcc"
704 if (cons) {
705 if (
706 #line 292 "matchcom.pcc"
707 (cons->view_selectors != 0)
708 #line 292 "matchcom.pcc"
711 #line 293 "matchcom.pcc"
713 #line 293 "matchcom.pcc"
714 #line 325 "matchcom.pcc"
716 int _V1 = arity_of(cons->ty);
717 Ty _V2 = deref(cons->ty);
718 switch (_V1) {
719 case 0: {
720 #line 294 "matchcom.pcc"
721 bug ("decor_view()");
722 #line 294 "matchcom.pcc"
723 } break;
724 case 1: {
725 #line 296 "matchcom.pcc"
726 decor(pat,view_selector_of(cons,pat,sel,cons->ty),
727 polarity,visible,E,match_rule);
728 #line 297 "matchcom.pcc"
729 } break;
730 default: {
731 if (pat) {
732 switch (pat->tag__) {
733 case a_Pat::tag_TUPLEpat: {
734 if (_V2) {
735 switch (_V2->tag__) {
736 case a_Ty::tag_TYCONty: {
737 if (boxed(((Ty_TYCONty *)_V2)->_1)) {
738 L11:;
739 #line 325 "matchcom.pcc"
740 error ("%Lbad view constructor pattern: %p", pat);
741 #line 325 "matchcom.pcc"
742 } else {
743 switch ((int)((Ty_TYCONty *)_V2)->_1) {
744 case ((int)TUPLEtycon): {
745 #line 299 "matchcom.pcc"
746 int i;
748 #line 300 "matchcom.pcc"
749 a_List<Pat> *
750 #line 300 "matchcom.pcc"
751 pat_list;
752 a_List<Ty> *
753 #line 301 "matchcom.pcc"
754 ty_list;
755 for (i = 0, pat_list = ((Pat_TUPLEpat *)pat)->TUPLEpat, ty_list = ((Ty_TYCONty *)_V2)->_2;
756 pat_list && ty_list;
757 pat_list = pat_list->_2, ty_list = ty_list->_2)
758 { decor(pat_list->_1,view_selector_of(cons,pat,sel,ty_list->_1),
759 polarity,visible,E,match_rule);
760 i++;
762 } break;
763 default: { goto L11; } break;
766 } break;
767 default: { goto L11; } break;
769 } else { goto L11; }
770 } break;
771 case a_Pat::tag_RECORDpat: {
772 if (_V2) {
773 switch (_V2->tag__) {
774 case a_Ty::tag_TYCONty: {
775 if (boxed(((Ty_TYCONty *)_V2)->_1)) {
776 switch (((Ty_TYCONty *)_V2)->_1->tag__) {
777 case a_TyCon::tag_RECORDtycon: {
778 #line 311 "matchcom.pcc"
779 for_each (LabPat, p, ((Pat_RECORDpat *)pat)->_1)
780 { int i;
782 #line 313 "matchcom.pcc"
783 a_List<Id> *
784 #line 313 "matchcom.pcc"
785 lab_list;
786 a_List<Ty> *
787 #line 314 "matchcom.pcc"
788 ty_list;
789 for (i = 0, lab_list = ((TyCon_RECORDtycon *)((Ty_TYCONty *)_V2)->_1)->_1, ty_list = ((Ty_TYCONty *)_V2)->_2;
790 lab_list && ty_list;
791 lab_list = lab_list->_2, ty_list = ty_list->_2, i++)
792 { if (lab_list->_1 == p.label)
793 decor(p.pat,view_selector_of(cons,pat,sel,ty_list->_1),
794 polarity,visible,E,match_rule);
797 } break;
798 default: { goto L11; } break;
800 } else { goto L11; }
801 } break;
802 default: { goto L11; } break;
804 } else { goto L11; }
805 } break;
806 default: { goto L11; } break;
808 } else { goto L11; }
812 #line 326 "matchcom.pcc"
813 #line 326 "matchcom.pcc"
816 #line 327 "matchcom.pcc"
817 } else {
819 #line 329 "matchcom.pcc"
820 error ("%Lmissing view selector for pattern: %p", pat);
821 #line 329 "matchcom.pcc"
823 } else {}
825 #line 331 "matchcom.pcc"
826 #line 331 "matchcom.pcc"
830 ///////////////////////////////////////////////////////////////////////////////
832 // Decorate patterns with selector bindings.
834 ///////////////////////////////////////////////////////////////////////////////
835 void decor
836 (Pat pat, Exp sel, Polarity polarity, Bool visible, PatternVarEnv& E,
837 int& match_rule)
838 { for(;;) {
839 if (! boxed(pat)) return;
840 pat->selector = sel; // annotate selector
842 #line 345 "matchcom.pcc"
843 #line 457 "matchcom.pcc"
845 if (pat) {
846 switch (pat->tag__) {
847 case a_Pat::tag_IDpat: {
848 #line 361 "matchcom.pcc"
849 if (visible)
850 { Exp exp = E.add(((Pat_IDpat *)pat)->_1,sel,((Pat_IDpat *)pat)->_2,polarity);
851 if (E.separate_guard() && ! E.tree_grammar() && exp != NOexp)
852 E.add_guard(EQexp(((Pat_IDpat *)pat)->_2,sel,exp));
853 else
854 ((Pat_IDpat *)pat)->_3 = exp;
856 return;
858 #line 369 "matchcom.pcc"
859 } break;
860 case a_Pat::tag_APPpat: {
861 if (((Pat_APPpat *)pat)->_1) {
862 switch (((Pat_APPpat *)pat)->_1->tag__) {
863 case a_Pat::tag_CONSpat: {
864 if (((Pat_CONSpat *)((Pat_APPpat *)pat)->_1)->CONSpat) {
865 if (((Pat_CONSpat *)((Pat_APPpat *)pat)->_1)->CONSpat->alg_ty) {
866 switch (((Pat_CONSpat *)((Pat_APPpat *)pat)->_1)->CONSpat->alg_ty->tag__) {
867 case a_Ty::tag_TYCONty: {
868 if (boxed(((Ty_TYCONty *)((Pat_CONSpat *)((Pat_APPpat *)pat)->_1)->CONSpat->alg_ty)->_1)) {
869 switch (((Ty_TYCONty *)((Pat_CONSpat *)((Pat_APPpat *)pat)->_1)->CONSpat->alg_ty)->_1->tag__) {
870 case a_TyCon::tag_DATATYPEtycon: {
871 if (
872 #line 435 "matchcom.pcc"
873 (((TyCon_DATATYPEtycon *)((Ty_TYCONty *)((Pat_CONSpat *)((Pat_APPpat *)pat)->_1)->CONSpat->alg_ty)->_1)->qualifiers & QUALview)
874 #line 435 "matchcom.pcc"
877 #line 436 "matchcom.pcc"
878 decor_view (((Pat_CONSpat *)((Pat_APPpat *)pat)->_1)->CONSpat,((Pat_APPpat *)pat)->_2,sel,polarity,visible,E,match_rule); return;
879 #line 436 "matchcom.pcc"
880 } else {
882 L12:;
883 #line 438 "matchcom.pcc"
884 decor(((Pat_APPpat *)pat)->_2,select(sel,((Pat_CONSpat *)((Pat_APPpat *)pat)->_1)->CONSpat),polarity,visible,E,match_rule); return;
885 #line 438 "matchcom.pcc"
887 } break;
888 default: { goto L12; } break;
890 } else { goto L12; }
891 } break;
892 default: { goto L12; } break;
894 } else { goto L12; }
895 } else { goto L12; }
896 } break;
897 default: {
898 L13:;
899 #line 457 "matchcom.pcc"
900 bug("decor()");
901 #line 457 "matchcom.pcc"
902 } break;
904 } else { goto L13; }
905 } break;
906 case a_Pat::tag_TYPEDpat: {
907 #line 383 "matchcom.pcc"
908 pat = ((Pat_TYPEDpat *)pat)->_1;
909 #line 383 "matchcom.pcc"
910 } break;
911 case a_Pat::tag_ASpat: {
912 #line 371 "matchcom.pcc"
913 if (visible)
914 { Exp exp = E.add(((Pat_ASpat *)pat)->_1,sel,((Pat_ASpat *)pat)->_3,polarity);
915 if (E.separate_guard() && ! E.tree_grammar() && exp != NOexp)
916 E.add_guard(EQexp(((Pat_ASpat *)pat)->_3,sel,exp));
917 else
918 ((Pat_ASpat *)pat)->_4 = exp;
920 pat = ((Pat_ASpat *)pat)->_2;
922 #line 379 "matchcom.pcc"
923 } break;
924 case a_Pat::tag_CONTEXTpat: {
925 #line 382 "matchcom.pcc"
926 pat = ((Pat_CONTEXTpat *)pat)->_2;
927 #line 382 "matchcom.pcc"
928 } break;
929 case a_Pat::tag_LEXEMEpat: {
930 if (
931 #line 347 "matchcom.pcc"
932 ((Pat_LEXEMEpat *)pat)->_4
933 #line 347 "matchcom.pcc"
936 #line 349 "matchcom.pcc"
937 if (visible)
938 { Ty t = NOty;
939 Exp binding =
940 CASTexp(((Pat_LEXEMEpat *)pat)->_2, BINOPexp("+",IDexp("rule__"),
941 LITERALexp(INTlit(((Pat_LEXEMEpat *)pat)->_4[0]->tag + 256 - 1 - match_rule))));
942 E.add(
943 #line 354 "matchcom.pcc"
944 #line 354 "matchcom.pcc"
945 _m_a_t_c_h_c_o_mco_c_c_Q1
946 #line 354 "matchcom.pcc"
947 #line 354 "matchcom.pcc"
948 , binding, t, polarity);
949 match_rule += ((Pat_LEXEMEpat *)pat)->_3 - 1;
951 return;
953 #line 358 "matchcom.pcc"
954 } else {
956 #line 359 "matchcom.pcc"
957 return;
958 #line 359 "matchcom.pcc"
960 } break;
961 case a_Pat::tag_ARRAYpat: {
962 #line 402 "matchcom.pcc"
963 int i = 0;
964 for_each (Pat,p,((Pat_ARRAYpat *)pat)->_1)
965 { decor(p,INDEXexp(sel,LITERALexp(INTlit(i))),polarity,visible,E,
966 match_rule);
967 i++;
969 return;
971 #line 409 "matchcom.pcc"
972 } break;
973 case a_Pat::tag_TUPLEpat: {
974 #line 386 "matchcom.pcc"
975 int i = 1;
976 for_each (Pat,p,((Pat_TUPLEpat *)pat)->TUPLEpat)
977 { decor(p,DOTexp(sel,index_of(i)),polarity,visible,E,match_rule);
978 i++;
980 return;
982 #line 392 "matchcom.pcc"
983 } break;
984 case a_Pat::tag_EXTUPLEpat: {
985 #line 394 "matchcom.pcc"
986 int i = 1;
987 for_each (Pat,p,((Pat_EXTUPLEpat *)pat)->EXTUPLEpat)
988 { decor(p,DOTexp(sel,index_of(i)),polarity,visible,E,match_rule);
989 i++;
991 return;
993 #line 400 "matchcom.pcc"
994 } break;
995 case a_Pat::tag_RECORDpat: {
996 #line 428 "matchcom.pcc"
997 for_each (LabPat,lab_pat,((Pat_RECORDpat *)pat)->_1)
998 decor(lab_pat.pat, DOTexp(sel,lab_pat.label),
999 polarity, visible, E, match_rule);
1000 return;
1002 #line 432 "matchcom.pcc"
1003 } break;
1004 case a_Pat::tag_LISTpat: {
1005 #line 450 "matchcom.pcc"
1006 for_each (Pat, apat, ((Pat_LISTpat *)pat)->head)
1007 { decor(apat,DOTexp(select(sel,((Pat_LISTpat *)pat)->cons),"_1"),polarity,visible,
1008 E,match_rule);
1009 sel = DOTexp(select(sel,((Pat_LISTpat *)pat)->cons),"_2");
1011 pat = ((Pat_LISTpat *)pat)->tail;
1013 #line 456 "matchcom.pcc"
1014 } break;
1015 case a_Pat::tag_VECTORpat: {
1016 #line 411 "matchcom.pcc"
1017 int i = 0;
1018 Exp s = select(sel,((Pat_VECTORpat *)pat)->cons);
1019 Exp len_exp = DOTexp(s,"len()");
1020 int n = length(((Pat_VECTORpat *)pat)->elements);
1021 for_each (Pat,p,((Pat_VECTORpat *)pat)->elements)
1022 { Exp index_exp =
1023 ((Pat_VECTORpat *)pat)->head_flex ? BINOPexp("-",len_exp,LITERALexp(INTlit(n-i)))
1024 : LITERALexp(INTlit(i));
1025 decor(p,APPexp(DOTexp(s,"at"),index_exp),polarity,visible,E,
1026 match_rule);
1027 i++;
1029 decor(((Pat_VECTORpat *)pat)->len,len_exp,polarity,visible,E,match_rule);
1030 decor(((Pat_VECTORpat *)pat)->array,DOTexp(s,"array()"),polarity,visible,E,match_rule);
1031 return;
1033 #line 426 "matchcom.pcc"
1034 } break;
1035 case a_Pat::tag_GUARDpat: {
1036 #line 384 "matchcom.pcc"
1037 pat = ((Pat_GUARDpat *)pat)->_1;
1038 #line 384 "matchcom.pcc"
1039 } break;
1040 case a_Pat::tag_LOGICALpat: {
1041 switch (((Pat_LOGICALpat *)pat)->_1) {
1042 case NOTpat: {
1043 #line 439 "matchcom.pcc"
1044 polarity = rev(polarity); pat = ((Pat_LOGICALpat *)pat)->_2;
1045 #line 439 "matchcom.pcc"
1046 } break;
1047 case ANDpat: {
1048 #line 441 "matchcom.pcc"
1049 decor(((Pat_LOGICALpat *)pat)->_2,sel,polarity,visible,E,match_rule); pat = ((Pat_LOGICALpat *)pat)->_3;
1050 #line 441 "matchcom.pcc"
1051 } break;
1052 case ORpat: {
1053 #line 442 "matchcom.pcc"
1054 decor(((Pat_LOGICALpat *)pat)->_2,sel,polarity,false,E,match_rule);
1055 pat = ((Pat_LOGICALpat *)pat)->_3; visible = false;
1057 #line 444 "matchcom.pcc"
1058 } break;
1059 default: {
1060 #line 446 "matchcom.pcc"
1061 decor(((Pat_LOGICALpat *)pat)->_2,sel,ISneither,false,E,match_rule);
1062 pat = ((Pat_LOGICALpat *)pat)->_3; visible = false; polarity = ISneither;
1064 #line 448 "matchcom.pcc"
1065 } break;
1067 } break;
1068 case a_Pat::tag_UNIFYpat: {
1069 #line 381 "matchcom.pcc"
1070 pat = ((Pat_UNIFYpat *)pat)->_1;
1071 #line 381 "matchcom.pcc"
1072 } break;
1073 case a_Pat::tag_MARKEDpat: {
1074 #line 380 "matchcom.pcc"
1075 pat = ((Pat_MARKEDpat *)pat)->_2;
1076 #line 380 "matchcom.pcc"
1077 } break;
1078 case a_Pat::tag_WILDpat:
1079 case a_Pat::tag_CONSpat:
1080 case a_Pat::tag_LITERALpat: {
1081 L14:;
1082 #line 346 "matchcom.pcc"
1083 return;
1084 #line 346 "matchcom.pcc"
1085 } break;
1086 default: { goto L13; } break;
1088 } else { goto L14; }
1090 #line 458 "matchcom.pcc"
1091 #line 458 "matchcom.pcc"
1096 ///////////////////////////////////////////////////////////////////////////////
1098 // Decorate a pattern list with bindings.
1100 ///////////////////////////////////////////////////////////////////////////////
1101 void decor
1102 (MatchExps exps, Pat pat, Polarity polarity, Bool visible,
1103 PatternVarEnv& E, int& match_rule)
1105 int arity = length(exps);
1106 if (arity == 1) {
1108 #line 473 "matchcom.pcc"
1109 #line 475 "matchcom.pcc"
1111 MatchExp _V3 = exps->_1;
1112 #line 475 "matchcom.pcc"
1113 decor(pat,_V3->_2 ? IDexp(_V3->_2) : _V3->_1, polarity, visible, E, match_rule);
1114 #line 475 "matchcom.pcc"
1116 #line 476 "matchcom.pcc"
1117 #line 476 "matchcom.pcc"
1119 } else {
1121 #line 478 "matchcom.pcc"
1122 #line 509 "matchcom.pcc"
1124 if (pat) {
1125 switch (pat->tag__) {
1126 case a_Pat::tag_WILDpat: {
1127 #line 479 "matchcom.pcc"
1128 /* skip */
1129 #line 479 "matchcom.pcc"
1130 } break;
1131 case a_Pat::tag_CONTEXTpat: {
1132 #line 481 "matchcom.pcc"
1133 decor(exps,((Pat_CONTEXTpat *)pat)->_2,polarity,visible,E,match_rule);
1134 #line 481 "matchcom.pcc"
1135 } break;
1136 case a_Pat::tag_TUPLEpat: {
1137 if (
1138 #line 482 "matchcom.pcc"
1139 (length(((Pat_TUPLEpat *)pat)->TUPLEpat) == arity)
1140 #line 482 "matchcom.pcc"
1143 #line 483 "matchcom.pcc"
1144 Pats ps;
1145 MatchExps es;
1146 for (ps = ((Pat_TUPLEpat *)pat)->TUPLEpat, es = exps; ps; ps = ps->_2, es = es->_2)
1148 #line 486 "matchcom.pcc"
1149 #line 490 "matchcom.pcc"
1151 MatchExp _V4 = es->_1;
1152 #line 488 "matchcom.pcc"
1153 decor(ps->_1,_V4->_2 ? IDexp(_V4->_2) : _V4->_1, polarity,
1154 visible, E, match_rule);
1156 #line 490 "matchcom.pcc"
1158 #line 491 "matchcom.pcc"
1159 #line 491 "matchcom.pcc"
1163 #line 493 "matchcom.pcc"
1164 } else {
1166 L15:;
1167 #line 508 "matchcom.pcc"
1168 error ("%Larity mismatch (expecting %i) in pattern: %p\n",
1169 arity, pat);
1170 #line 509 "matchcom.pcc"
1172 } break;
1173 case a_Pat::tag_LOGICALpat: {
1174 switch (((Pat_LOGICALpat *)pat)->_1) {
1175 case NOTpat: {
1176 #line 495 "matchcom.pcc"
1177 decor(exps,((Pat_LOGICALpat *)pat)->_2,rev(polarity),false,E,match_rule);
1178 #line 495 "matchcom.pcc"
1179 } break;
1180 case ANDpat: {
1181 #line 497 "matchcom.pcc"
1182 decor(exps,((Pat_LOGICALpat *)pat)->_2,polarity,visible,E,match_rule);
1183 decor(exps,((Pat_LOGICALpat *)pat)->_3,polarity,visible,E,match_rule);
1185 #line 499 "matchcom.pcc"
1186 } break;
1187 case ORpat: {
1188 #line 501 "matchcom.pcc"
1189 decor(exps,((Pat_LOGICALpat *)pat)->_2,polarity,false,E,match_rule);
1190 decor(exps,((Pat_LOGICALpat *)pat)->_3,polarity,false,E,match_rule);
1192 #line 503 "matchcom.pcc"
1193 } break;
1194 default: {
1195 #line 505 "matchcom.pcc"
1196 decor(exps,((Pat_LOGICALpat *)pat)->_2,ISneither,false,E,match_rule);
1197 decor(exps,((Pat_LOGICALpat *)pat)->_3,ISneither,false,E,match_rule);
1199 #line 507 "matchcom.pcc"
1200 } break;
1202 } break;
1203 case a_Pat::tag_MARKEDpat: {
1204 #line 480 "matchcom.pcc"
1205 decor(exps,((Pat_MARKEDpat *)pat)->_2,polarity,visible,E,match_rule);
1206 #line 480 "matchcom.pcc"
1207 } break;
1208 default: { goto L15; } break;
1210 } else { goto L15; }
1212 #line 510 "matchcom.pcc"
1213 #line 510 "matchcom.pcc"
1218 ///////////////////////////////////////////////////////////////////////////////
1220 // Return the arity of a pattern
1222 ///////////////////////////////////////////////////////////////////////////////
1223 #line 519 "matchcom.pcc"
1224 #line 533 "matchcom.pcc"
1225 int arity_of (Pat x_1);
1226 int arity_of (Pat x_1)
1228 if (x_1) {
1229 switch (x_1->tag__) {
1230 case a_Pat::tag_CONTEXTpat: {
1231 #line 523 "matchcom.pcc"
1232 return arity_of(((Pat_CONTEXTpat *)x_1)->_2);
1233 #line 524 "matchcom.pcc"
1234 } break;
1235 case a_Pat::tag_TUPLEpat: {
1236 #line 519 "matchcom.pcc"
1237 return length(((Pat_TUPLEpat *)x_1)->TUPLEpat);
1238 #line 520 "matchcom.pcc"
1239 } break;
1240 case a_Pat::tag_RECORDpat: {
1241 if ((! ((Pat_RECORDpat *)x_1)->_2)) {
1243 #line 520 "matchcom.pcc"
1244 return length(((Pat_RECORDpat *)x_1)->_1);
1245 #line 521 "matchcom.pcc"
1246 } else {
1248 #line 531 "matchcom.pcc"
1249 error ("%Lillegal incomplete record pattern: %p\n",x_1); return 0;
1250 #line 531 "matchcom.pcc"
1252 } break;
1253 case a_Pat::tag_LOGICALpat: {
1254 switch (((Pat_LOGICALpat *)x_1)->_1) {
1255 case NOTpat: {
1256 #line 522 "matchcom.pcc"
1257 return arity_of(((Pat_LOGICALpat *)x_1)->_2);
1258 #line 523 "matchcom.pcc"
1259 } break;
1260 default: {
1261 #line 525 "matchcom.pcc"
1262 int i = arity_of(((Pat_LOGICALpat *)x_1)->_2);
1263 int j = arity_of(((Pat_LOGICALpat *)x_1)->_3);
1264 if (i != j) error ("%Larity mismatch in logical pattern: %p\n",x_1);
1265 return i;
1267 #line 529 "matchcom.pcc"
1268 } break;
1270 } break;
1271 case a_Pat::tag_MARKEDpat: {
1272 #line 521 "matchcom.pcc"
1273 return arity_of(((Pat_MARKEDpat *)x_1)->_2);
1274 #line 522 "matchcom.pcc"
1275 } break;
1276 default: {
1277 L16:;
1278 #line 532 "matchcom.pcc"
1279 return 1;
1280 #line 532 "matchcom.pcc"
1281 } break;
1283 } else { goto L16; }
1285 #line 533 "matchcom.pcc"
1286 #line 533 "matchcom.pcc"
1289 ///////////////////////////////////////////////////////////////////////////////
1291 // Make a list of match expressions
1293 ///////////////////////////////////////////////////////////////////////////////
1294 MatchExps make_match_exps(int i, int n, int j)
1295 { if (i > n) return
1296 #line 541 "matchcom.pcc"
1297 #line 541 "matchcom.pcc"
1298 nil_1_
1299 #line 541 "matchcom.pcc"
1300 #line 541 "matchcom.pcc"
1302 else {
1303 Exp e = j < 0 ? IDexp(index_of(i,"x")) : RELexp(j);
1304 return
1305 #line 544 "matchcom.pcc"
1306 #line 544 "matchcom.pcc"
1307 list_1_(MATCHexp(e,nil_1_),make_match_exps((i + 1),n,j))
1308 #line 544 "matchcom.pcc"
1309 #line 544 "matchcom.pcc"
1314 ///////////////////////////////////////////////////////////////////////////////
1316 // Main decoration routine
1318 ///////////////////////////////////////////////////////////////////////////////
1319 void decor(MatchExps& exps, Pat pat, PatternVarEnv& E, int& match_rule, int i)
1320 { if (exps ==
1321 #line 554 "matchcom.pcc"
1322 #line 554 "matchcom.pcc"
1323 nil_1_
1324 #line 554 "matchcom.pcc"
1325 #line 554 "matchcom.pcc"
1326 ) // create default match expressions if there are none
1327 exps = make_match_exps(1,arity_of(pat), i);
1328 decor(exps,pat,ISpositive,true,E,match_rule);
1331 ///////////////////////////////////////////////////////////////////////////////
1333 // Translate a string literal into a character array pattern.
1335 ///////////////////////////////////////////////////////////////////////////////
1336 #line 564 "matchcom.pcc"
1337 a_List<Pat> *
1338 #line 564 "matchcom.pcc"
1339 make_string_pattern (const char * string)
1340 { if (string[0] == '\"' && string[1] == '\0') {
1341 return
1342 #line 566 "matchcom.pcc"
1343 list_1_(LITERALpat(CHARlit('\000')))
1344 #line 566 "matchcom.pcc"
1345 #line 566 "matchcom.pcc"
1347 } else {
1348 char c;
1349 const char * next_pos = parse_char(string,c);
1351 #line 570 "matchcom.pcc"
1352 a_List<Pat> *
1353 #line 570 "matchcom.pcc"
1354 pats = make_string_pattern(next_pos);
1355 return
1356 #line 571 "matchcom.pcc"
1357 list_1_(LITERALpat(CHARlit(c)),pats)
1358 #line 571 "matchcom.pcc"
1359 #line 571 "matchcom.pcc"
1364 ///////////////////////////////////////////////////////////////////////////////
1366 // Translate a pattern into a matching tree.
1368 ///////////////////////////////////////////////////////////////////////////////
1369 Match MatchCompiler::trans(Pat pat, Pos pos, Bool neg, Match yes, Match no)
1371 #line 581 "matchcom.pcc"
1372 #line 697 "matchcom.pcc"
1374 for (;;) {
1375 if (pat) {
1376 switch (pat->tag__) {
1377 case a_Pat::tag_WILDpat: {
1378 L18:;
1379 #line 582 "matchcom.pcc"
1380 return neg ? no : yes;
1381 #line 582 "matchcom.pcc"
1382 } break;
1383 case a_Pat::tag_IDpat: {
1384 if (((Pat_IDpat *)pat)->_3) {
1385 #line 589 "matchcom.pcc"
1386 return GUARDmatch(EQexp(((Pat_IDpat *)pat)->_2,pat->selector,((Pat_IDpat *)pat)->_3),
1387 neg ? no : yes, neg ? yes : no);
1388 #line 590 "matchcom.pcc"
1389 } else { goto L18; }
1390 } break;
1391 case a_Pat::tag_CONSpat: {
1392 if (((Pat_CONSpat *)pat)->CONSpat) {
1393 if (((Pat_CONSpat *)pat)->CONSpat->alg_ty) {
1394 switch (((Pat_CONSpat *)pat)->CONSpat->alg_ty->tag__) {
1395 case a_Ty::tag_TYCONty: {
1396 if (boxed(((Ty_TYCONty *)((Pat_CONSpat *)pat)->CONSpat->alg_ty)->_1)) {
1397 switch (((Ty_TYCONty *)((Pat_CONSpat *)pat)->CONSpat->alg_ty)->_1->tag__) {
1398 case a_TyCon::tag_DATATYPEtycon: {
1399 #line 652 "matchcom.pcc"
1400 int arity = ((TyCon_DATATYPEtycon *)((Ty_TYCONty *)((Pat_CONSpat *)pat)->CONSpat->alg_ty)->_1)->unit + ((TyCon_DATATYPEtycon *)((Ty_TYCONty *)((Pat_CONSpat *)pat)->CONSpat->alg_ty)->_1)->arg;
1401 Match * m = Matches(arity);
1402 for (int i = arity - 1; i >= 0; i--) m[i] = neg ? yes : no;
1403 m[((Pat_CONSpat *)pat)->CONSpat->tag] = neg ? no : yes;
1404 return CONSmatch(pos,pat->selector,pat->ty,((Pat_CONSpat *)pat)->CONSpat->alg_ty,arity,m,neg ? yes : no);
1406 #line 657 "matchcom.pcc"
1407 } break;
1408 default: {
1409 L19:;
1410 #line 697 "matchcom.pcc"
1411 bug("MatchCompiler::trans(): %p", pat);
1412 #line 697 "matchcom.pcc"
1413 } break;
1415 } else { goto L19; }
1416 } break;
1417 default: { goto L19; } break;
1419 } else { goto L19; }
1420 } else {
1421 L20:;
1422 #line 696 "matchcom.pcc"
1423 return neg ? no : yes;
1424 #line 696 "matchcom.pcc"
1426 } break;
1427 case a_Pat::tag_APPpat: {
1428 if (((Pat_APPpat *)pat)->_1) {
1429 switch (((Pat_APPpat *)pat)->_1->tag__) {
1430 case a_Pat::tag_CONSpat: {
1431 if (((Pat_CONSpat *)((Pat_APPpat *)pat)->_1)->CONSpat) {
1432 if (((Pat_CONSpat *)((Pat_APPpat *)pat)->_1)->CONSpat->alg_ty) {
1433 switch (((Pat_CONSpat *)((Pat_APPpat *)pat)->_1)->CONSpat->alg_ty->tag__) {
1434 case a_Ty::tag_TYCONty: {
1435 if (boxed(((Ty_TYCONty *)((Pat_CONSpat *)((Pat_APPpat *)pat)->_1)->CONSpat->alg_ty)->_1)) {
1436 switch (((Ty_TYCONty *)((Pat_CONSpat *)((Pat_APPpat *)pat)->_1)->CONSpat->alg_ty)->_1->tag__) {
1437 case a_TyCon::tag_DATATYPEtycon: {
1438 #line 640 "matchcom.pcc"
1439 int arity = ((TyCon_DATATYPEtycon *)((Ty_TYCONty *)((Pat_CONSpat *)((Pat_APPpat *)pat)->_1)->CONSpat->alg_ty)->_1)->unit + ((TyCon_DATATYPEtycon *)((Ty_TYCONty *)((Pat_CONSpat *)((Pat_APPpat *)pat)->_1)->CONSpat->alg_ty)->_1)->arg;
1440 Match * m = Matches(arity);
1441 int i;
1442 for (i = arity - 1; i >= 0; i--) m[i] = neg ? yes : no;
1443 i = ((Pat_CONSpat *)((Pat_APPpat *)pat)->_1)->CONSpat->tag + ((TyCon_DATATYPEtycon *)((Ty_TYCONty *)((Pat_CONSpat *)((Pat_APPpat *)pat)->_1)->CONSpat->alg_ty)->_1)->unit;
1444 m[i] = trans(((Pat_APPpat *)pat)->_2,POSint(i,pos),neg,yes,no);
1445 return CONSmatch(pos,pat->selector,pat->ty,((Pat_CONSpat *)((Pat_APPpat *)pat)->_1)->CONSpat->alg_ty,arity,m,neg ? yes : no);
1447 #line 647 "matchcom.pcc"
1448 } break;
1449 default: { goto L19; } break;
1451 } else { goto L19; }
1452 } break;
1453 default: { goto L19; } break;
1455 } else { goto L19; }
1456 } else { goto L20; }
1457 } break;
1458 default: { goto L19; } break;
1460 } else { goto L19; }
1461 } break;
1462 case a_Pat::tag_TYPEDpat: {
1463 #line 584 "matchcom.pcc"
1464 pat = ((Pat_TYPEDpat *)pat)->_1;
1465 #line 584 "matchcom.pcc"
1466 } break;
1467 case a_Pat::tag_ASpat: {
1468 if (((Pat_ASpat *)pat)->_4) {
1469 #line 596 "matchcom.pcc"
1470 Exp guard = EQexp(((Pat_ASpat *)pat)->_3,pat->selector,((Pat_ASpat *)pat)->_4);
1471 if (neg) no = GUARDmatch(guard,no,yes);
1472 else yes = GUARDmatch(guard,yes,no);
1473 pat = ((Pat_ASpat *)pat)->_2;
1475 #line 600 "matchcom.pcc"
1476 } else {
1477 #line 583 "matchcom.pcc"
1478 pat = ((Pat_ASpat *)pat)->_2;
1479 #line 583 "matchcom.pcc"
1481 } break;
1482 case a_Pat::tag_LITERALpat: {
1483 #line 602 "matchcom.pcc"
1484 return LITERALmatch(pos,pat->selector,vec(((Pat_LITERALpat *)pat)->LITERALpat),1,vec(neg ? no : yes),
1485 neg ? yes : no);
1487 #line 604 "matchcom.pcc"
1488 } break;
1489 case a_Pat::tag_CONTEXTpat: {
1490 #line 586 "matchcom.pcc"
1491 pat = add_contexts(((Pat_CONTEXTpat *)pat)->_1,((Pat_CONTEXTpat *)pat)->_2);
1492 #line 586 "matchcom.pcc"
1493 } break;
1494 case a_Pat::tag_LEXEMEpat: {
1495 #line 587 "matchcom.pcc"
1496 pat = expand_lexeme_pat(pat,((Pat_LEXEMEpat *)pat)->_2,((Pat_LEXEMEpat *)pat)->_3,((Pat_LEXEMEpat *)pat)->_4);
1497 #line 587 "matchcom.pcc"
1498 } break;
1499 case a_Pat::tag_ARRAYpat: {
1500 #line 623 "matchcom.pcc"
1501 return trans(((Pat_ARRAYpat *)pat)->_1,0,pos,neg,yes,no);
1502 #line 623 "matchcom.pcc"
1503 } break;
1504 case a_Pat::tag_TUPLEpat: {
1505 #line 606 "matchcom.pcc"
1506 if (current_index_map) {
1507 HashTable::Entry * e = current_index_map->lookup(pos);
1508 if (e)
1509 return trans(((Pat_TUPLEpat *)pat)->TUPLEpat,pos,neg,yes,no,
1510 (int *)current_index_map->value(e));
1512 return trans(((Pat_TUPLEpat *)pat)->TUPLEpat,0,pos,neg,yes,no);
1514 #line 613 "matchcom.pcc"
1515 } break;
1516 case a_Pat::tag_EXTUPLEpat: {
1517 #line 615 "matchcom.pcc"
1518 if (current_index_map) {
1519 HashTable::Entry * e = current_index_map->lookup(pos);
1520 if (e)
1521 return trans(((Pat_EXTUPLEpat *)pat)->EXTUPLEpat,pos,neg,yes,no,
1522 (int *)current_index_map->value(e));
1524 return trans(((Pat_EXTUPLEpat *)pat)->EXTUPLEpat,0,pos,neg,yes,no);
1526 #line 622 "matchcom.pcc"
1527 } break;
1528 case a_Pat::tag_RECORDpat: {
1529 #line 634 "matchcom.pcc"
1530 return trans(((Pat_RECORDpat *)pat)->_1,pos,neg,yes,no);
1531 #line 634 "matchcom.pcc"
1532 } break;
1533 case a_Pat::tag_LISTpat: {
1534 if (((Pat_LISTpat *)pat)->cons) {
1535 if (((Pat_LISTpat *)pat)->head) {
1536 L21:;
1537 #line 685 "matchcom.pcc"
1538 Pat new_tail =
1539 #line 685 "matchcom.pcc"
1540 #line 685 "matchcom.pcc"
1541 LISTpat(((Pat_LISTpat *)pat)->cons, ((Pat_LISTpat *)pat)->nil, ((Pat_LISTpat *)pat)->head->_2, ((Pat_LISTpat *)pat)->tail)
1542 #line 685 "matchcom.pcc"
1543 #line 685 "matchcom.pcc"
1545 Pat list_pat = APPpat(CONSpat(((Pat_LISTpat *)pat)->cons),TUPLEpat(
1546 #line 686 "matchcom.pcc"
1547 #line 686 "matchcom.pcc"
1548 list_1_(((Pat_LISTpat *)pat)->head->_1,list_1_(new_tail))
1549 #line 686 "matchcom.pcc"
1550 #line 686 "matchcom.pcc"
1552 new_tail->selector = DOTexp(select(pat->selector,((Pat_LISTpat *)pat)->cons),"_2");
1553 list_pat->selector = pat->selector;
1554 pat = list_pat;
1556 #line 690 "matchcom.pcc"
1557 } else {
1558 L22:;
1559 if (((Pat_LISTpat *)pat)->tail) {
1560 L23:;
1561 #line 683 "matchcom.pcc"
1562 pat = ((Pat_LISTpat *)pat)->tail;
1563 #line 683 "matchcom.pcc"
1564 } else {
1565 L24:;
1566 #line 682 "matchcom.pcc"
1567 Pat p = CONSpat(((Pat_LISTpat *)pat)->nil); p->selector = pat->selector; pat = p;
1568 #line 682 "matchcom.pcc"
1571 } else {
1572 if (((Pat_LISTpat *)pat)->head) { goto L21; } else { goto L22; }
1574 } break;
1575 case a_Pat::tag_VECTORpat: {
1576 #line 625 "matchcom.pcc"
1577 int low = length(((Pat_VECTORpat *)pat)->elements);
1578 int high = (((Pat_VECTORpat *)pat)->head_flex || ((Pat_VECTORpat *)pat)->tail_flex) ? INT_MAX : low;
1579 int start = ((Pat_VECTORpat *)pat)->head_flex ? (INT_MAX - length(((Pat_VECTORpat *)pat)->elements)) : 0;
1580 Match p1 = trans(((Pat_VECTORpat *)pat)->elements,start,pos,neg,yes,no);
1581 Match p2 = trans(((Pat_VECTORpat *)pat)->array,pos,neg,(neg ? no : p1),(neg ? p1 : no));
1582 Match p3 = trans(((Pat_VECTORpat *)pat)->len,pos,neg,(neg ? no : p2),(neg ? p3 : no));
1583 return RANGEmatch(pos,ARROWexp(pat->selector,"len()"),low,high,
1584 (neg ? no : p3), (neg ? p3 : no));
1586 #line 633 "matchcom.pcc"
1587 } break;
1588 case a_Pat::tag_GUARDpat: {
1589 #line 592 "matchcom.pcc"
1590 Match m = trans(((Pat_GUARDpat *)pat)->_1,pos,neg,yes,no);
1591 return GUARDmatch(((Pat_GUARDpat *)pat)->_2, neg ? no : m, neg ? m : no);
1593 #line 594 "matchcom.pcc"
1594 } break;
1595 case a_Pat::tag_LOGICALpat: {
1596 switch (((Pat_LOGICALpat *)pat)->_1) {
1597 case NOTpat: {
1598 #line 659 "matchcom.pcc"
1599 return trans(((Pat_LOGICALpat *)pat)->_2, pos,! neg, yes, no);
1600 #line 659 "matchcom.pcc"
1601 } break;
1602 case ANDpat: {
1603 #line 661 "matchcom.pcc"
1604 return neg ? merge(trans(((Pat_LOGICALpat *)pat)->_2,pos,neg,yes,no),trans(((Pat_LOGICALpat *)pat)->_3,pos,neg,yes,no))
1605 : trans(((Pat_LOGICALpat *)pat)->_2, pos, neg, trans(((Pat_LOGICALpat *)pat)->_3, pos, neg, yes, no), no);
1607 #line 663 "matchcom.pcc"
1608 } break;
1609 case ORpat: {
1610 #line 665 "matchcom.pcc"
1611 return neg ? trans(((Pat_LOGICALpat *)pat)->_2, pos, neg, trans(((Pat_LOGICALpat *)pat)->_3, pos, neg, yes, no), no)
1612 : merge(trans(((Pat_LOGICALpat *)pat)->_2,pos,neg,yes,no),trans(((Pat_LOGICALpat *)pat)->_3,pos,neg,yes,no));
1614 #line 667 "matchcom.pcc"
1615 } break;
1616 case EQUIVpat: {
1617 #line 671 "matchcom.pcc"
1618 pat = LOGICALpat(ORpat,
1619 LOGICALpat(ANDpat, ((Pat_LOGICALpat *)pat)->_2, ((Pat_LOGICALpat *)pat)->_3),
1620 LOGICALpat(ANDpat, LOGICALpat(NOTpat,((Pat_LOGICALpat *)pat)->_2,NOpat),
1621 LOGICALpat(NOTpat,((Pat_LOGICALpat *)pat)->_3,NOpat)));
1623 #line 675 "matchcom.pcc"
1624 } break;
1625 case XORpat: {
1626 #line 677 "matchcom.pcc"
1627 pat = LOGICALpat(ORpat,
1628 LOGICALpat(ANDpat, ((Pat_LOGICALpat *)pat)->_2, LOGICALpat(NOTpat,((Pat_LOGICALpat *)pat)->_3,NOpat)),
1629 LOGICALpat(ANDpat, LOGICALpat(NOTpat,((Pat_LOGICALpat *)pat)->_2,NOpat), ((Pat_LOGICALpat *)pat)->_3));
1631 #line 680 "matchcom.pcc"
1632 } break;
1633 default: {
1634 #line 669 "matchcom.pcc"
1635 pat = LOGICALpat(ORpat, LOGICALpat(NOTpat,((Pat_LOGICALpat *)pat)->_2,NOpat), ((Pat_LOGICALpat *)pat)->_3);
1636 #line 669 "matchcom.pcc"
1637 } break;
1639 } break;
1640 case a_Pat::tag_MARKEDpat: {
1641 #line 585 "matchcom.pcc"
1642 pat = ((Pat_MARKEDpat *)pat)->_2;
1643 #line 585 "matchcom.pcc"
1644 } break;
1645 default: { goto L19; } break;
1647 } else { goto L18; }
1650 #line 698 "matchcom.pcc"
1651 #line 698 "matchcom.pcc"
1655 ///////////////////////////////////////////////////////////////////////////////
1657 // Translate a pattern list into a matching tree using ranking function.
1659 ///////////////////////////////////////////////////////////////////////////////
1660 Match MatchCompiler::trans
1661 (Pats ps, Pos pos, Bool neg, Match yes, Match no, int rank[])
1662 { Pat Ps[256];
1663 int i = 0;
1664 for_each (Pat, p, ps) Ps[i++] = p;
1665 int n = i;
1666 Match m = yes;
1667 for (i = n - 1; i >= 0; i--)
1668 m = trans(Ps[rank[i]], POSint(i, pos), neg, m, no);
1669 return m;
1672 ///////////////////////////////////////////////////////////////////////////////
1674 // Translate a pattern list into a matching tree.
1676 ///////////////////////////////////////////////////////////////////////////////
1677 Match MatchCompiler::trans
1678 (Pats ps, int i, Pos pos, Bool neg, Match yes, Match no)
1680 #line 725 "matchcom.pcc"
1681 #line 729 "matchcom.pcc"
1683 if (ps) {
1684 #line 727 "matchcom.pcc"
1685 return trans(ps->_1, POSint(i, pos), neg,
1686 trans(ps->_2, i+1, pos, neg, yes, no), no);
1688 #line 729 "matchcom.pcc"
1689 } else {
1690 #line 726 "matchcom.pcc"
1691 return yes;
1692 #line 726 "matchcom.pcc"
1695 #line 730 "matchcom.pcc"
1696 #line 730 "matchcom.pcc"
1700 ///////////////////////////////////////////////////////////////////////////////
1702 // Translate a labeled pattern list into a matching tree.
1704 ///////////////////////////////////////////////////////////////////////////////
1705 Match MatchCompiler::trans
1706 (LabPats ps, Pos pos, Bool neg, Match yes, Match no)
1708 #line 740 "matchcom.pcc"
1709 #line 744 "matchcom.pcc"
1711 if (ps) {
1712 #line 742 "matchcom.pcc"
1713 return trans(ps->_1.pat, POSlabel(ps->_1.label, pos), neg,
1714 trans(ps->_2, pos, neg, yes, no), no);
1716 #line 744 "matchcom.pcc"
1717 } else {
1718 #line 741 "matchcom.pcc"
1719 return yes;
1720 #line 741 "matchcom.pcc"
1723 #line 745 "matchcom.pcc"
1724 #line 745 "matchcom.pcc"
1728 ///////////////////////////////////////////////////////////////////////////////
1730 // Get the position list of a matching tree node.
1732 ///////////////////////////////////////////////////////////////////////////////
1733 #line 753 "matchcom.pcc"
1734 #line 759 "matchcom.pcc"
1735 Pos get_pos (Match x_1);
1736 Pos get_pos (Match x_1)
1738 if (boxed(x_1)) {
1739 switch (x_1->tag__) {
1740 case a_Match::tag_LITERALmatch: {
1741 #line 753 "matchcom.pcc"
1742 return ((Match_LITERALmatch *)x_1)->_1;
1743 #line 753 "matchcom.pcc"
1744 } break;
1745 case a_Match::tag_RANGEmatch: {
1746 #line 754 "matchcom.pcc"
1747 return ((Match_RANGEmatch *)x_1)->_1;
1748 #line 754 "matchcom.pcc"
1749 } break;
1750 case a_Match::tag_CONSmatch: {
1751 #line 755 "matchcom.pcc"
1752 return ((Match_CONSmatch *)x_1)->_1;
1753 #line 755 "matchcom.pcc"
1754 } break;
1755 case a_Match::tag_SUCCESSmatch:
1756 case a_Match::tag_SUCCESSESmatch:
1757 case a_Match::tag_COSTmatch: {
1758 #line 757 "matchcom.pcc"
1759 return POSinfinity;
1760 #line 757 "matchcom.pcc"
1761 } break;
1762 default: {
1763 L25:;
1764 #line 758 "matchcom.pcc"
1765 return POSzero;
1766 #line 758 "matchcom.pcc"
1767 } break;
1769 } else { goto L25; }
1771 #line 759 "matchcom.pcc"
1772 #line 759 "matchcom.pcc"
1775 ///////////////////////////////////////////////////////////////////////////////
1777 // Position list comparison result.
1779 ///////////////////////////////////////////////////////////////////////////////
1780 #line 766 "matchcom.pcc"
1781 #line 766 "matchcom.pcc"
1782 enum CompareResult {
1783 LESS = 0, SAME = 1, MORE = 2,
1784 NEITHER = 3
1790 #line 766 "matchcom.pcc"
1791 #line 766 "matchcom.pcc"
1794 ///////////////////////////////////////////////////////////////////////////////
1796 // Compare two position lists lexicographically.
1798 ///////////////////////////////////////////////////////////////////////////////
1799 CompareResult compare_pos(Pos a, Pos b)
1800 { Pos u, v;
1802 #line 775 "matchcom.pcc"
1803 #line 808 "matchcom.pcc"
1805 if (
1806 #line 776 "matchcom.pcc"
1807 (a == b)
1808 #line 776 "matchcom.pcc"
1811 #line 776 "matchcom.pcc"
1812 return SAME;
1813 #line 776 "matchcom.pcc"
1814 } else {
1816 if (boxed(a)) {
1817 switch (untagp(a)) {
1818 case a_Pos::tag_POSint: {
1819 if (boxed(b)) {
1820 switch (untagp(b)) {
1821 case a_Pos::tag_POSint: {
1822 #line 788 "matchcom.pcc"
1823 CompareResult r = compare_pos(((Pos_POSint *)a)->_2,((Pos_POSint *)b)->_2);
1824 if (r != SAME) return r;
1825 if (((Pos_POSint *)a)->_1 == ((Pos_POSint *)b)->_1) return SAME;
1826 if (((Pos_POSint *)a)->_1 < ((Pos_POSint *)b)->_1) return LESS;
1827 return MORE;
1829 #line 793 "matchcom.pcc"
1830 } break;
1831 case a_Pos::tag_POSlabel: {
1832 #line 781 "matchcom.pcc"
1833 u = ((Pos_POSint *)a)->_2; v = ((Pos_POSlabel *)derefp(b))->_2;
1834 #line 781 "matchcom.pcc"
1835 } break;
1836 default: {
1837 #line 782 "matchcom.pcc"
1838 u = ((Pos_POSint *)a)->_2; v = ((Pos_POSadaptive *)derefp(b))->_3;
1839 #line 782 "matchcom.pcc"
1840 } break;
1842 } else {
1843 if (b) {
1845 L26:;
1846 #line 780 "matchcom.pcc"
1847 return LESS;
1848 #line 780 "matchcom.pcc"
1849 } else {
1851 L27:;
1852 #line 778 "matchcom.pcc"
1853 return MORE;
1854 #line 778 "matchcom.pcc"
1857 } break;
1858 case a_Pos::tag_POSlabel: {
1859 if (boxed(b)) {
1860 switch (untagp(b)) {
1861 case a_Pos::tag_POSint: {
1862 #line 783 "matchcom.pcc"
1863 u = ((Pos_POSlabel *)derefp(a))->_2; v = ((Pos_POSint *)b)->_2;
1864 #line 783 "matchcom.pcc"
1865 } break;
1866 case a_Pos::tag_POSlabel: {
1867 #line 795 "matchcom.pcc"
1868 CompareResult r = compare_pos(((Pos_POSlabel *)derefp(a))->_2,((Pos_POSlabel *)derefp(b))->_2);
1869 if (r != SAME) return r;
1870 int s = strcmp(((Pos_POSlabel *)derefp(a))->_1,((Pos_POSlabel *)derefp(b))->_1);
1871 if (s == 0) return SAME;
1872 if (s < 0) return LESS;
1873 return MORE;
1875 #line 801 "matchcom.pcc"
1876 } break;
1877 default: {
1878 #line 784 "matchcom.pcc"
1879 u = ((Pos_POSlabel *)derefp(a))->_2; v = ((Pos_POSadaptive *)derefp(b))->_3;
1880 #line 784 "matchcom.pcc"
1881 } break;
1883 } else {
1884 if (b) {
1885 goto L26; } else {
1886 goto L27; }
1888 } break;
1889 default: {
1890 if (boxed(b)) {
1891 switch (untagp(b)) {
1892 case a_Pos::tag_POSint: {
1893 #line 785 "matchcom.pcc"
1894 u = ((Pos_POSint *)b)->_2; v = ((Pos_POSadaptive *)derefp(a))->_3;
1895 #line 785 "matchcom.pcc"
1896 } break;
1897 case a_Pos::tag_POSlabel: {
1898 #line 786 "matchcom.pcc"
1899 u = ((Pos_POSlabel *)derefp(b))->_2; v = ((Pos_POSadaptive *)derefp(a))->_3;
1900 #line 786 "matchcom.pcc"
1901 } break;
1902 default: {
1903 #line 803 "matchcom.pcc"
1904 CompareResult r = compare_pos(((Pos_POSadaptive *)derefp(a))->_3,((Pos_POSadaptive *)derefp(b))->_3);
1905 if (r != SAME) return r;
1906 if (((Pos_POSadaptive *)derefp(a))->_2[((Pos_POSadaptive *)derefp(a))->_1] == ((Pos_POSadaptive *)derefp(b))->_2[((Pos_POSadaptive *)derefp(b))->_1]) return SAME;
1907 if (((Pos_POSadaptive *)derefp(a))->_2[((Pos_POSadaptive *)derefp(a))->_1] < ((Pos_POSadaptive *)derefp(b))->_2[((Pos_POSadaptive *)derefp(b))->_1]) return LESS;
1908 return MORE;
1910 #line 808 "matchcom.pcc"
1911 } break;
1913 } else {
1914 if (b) {
1915 goto L26; } else {
1916 goto L27; }
1918 } break;
1920 } else {
1921 if (a) {
1923 if (boxed(b)) {
1924 L28:;
1925 #line 779 "matchcom.pcc"
1926 return MORE;
1927 #line 779 "matchcom.pcc"
1928 } else {
1929 if (b) {
1930 goto L28; } else {
1931 goto L27; }
1933 } else {
1935 #line 777 "matchcom.pcc"
1936 return LESS;
1937 #line 777 "matchcom.pcc"
1942 #line 809 "matchcom.pcc"
1943 #line 809 "matchcom.pcc"
1946 CompareResult r = compare_pos(u,v);
1947 if (r != SAME) return r;
1948 return NEITHER;
1951 ///////////////////////////////////////////////////////////////////////////////
1953 // Compare two position lists lexicographically.
1955 ///////////////////////////////////////////////////////////////////////////////
1956 Bool pos_equal(HashTable::Key p, HashTable::Key q)
1957 { return compare_pos((Pos)p, (Pos)q) == SAME; }
1959 ///////////////////////////////////////////////////////////////////////////////
1961 // Compare two literals.
1963 ///////////////////////////////////////////////////////////////////////////////
1964 #line 829 "matchcom.pcc"
1965 #line 838 "matchcom.pcc"
1966 int compare_literals (Literal x_1, Literal x_2);
1967 int compare_literals (Literal x_1, Literal x_2)
1969 switch (x_1->tag__) {
1970 case a_Literal::tag_INTlit: {
1971 switch (x_2->tag__) {
1972 case a_Literal::tag_INTlit: {
1973 #line 829 "matchcom.pcc"
1974 return ((Literal_INTlit *)x_1)->INTlit - ((Literal_INTlit *)x_2)->INTlit;
1975 #line 829 "matchcom.pcc"
1976 } break;
1977 default: {
1978 L29:;
1979 #line 837 "matchcom.pcc"
1980 return 1;
1981 #line 837 "matchcom.pcc"
1982 } break;
1984 } break;
1985 case a_Literal::tag_BOOLlit: {
1986 switch (x_2->tag__) {
1987 case a_Literal::tag_BOOLlit: {
1988 #line 832 "matchcom.pcc"
1989 return ((Literal_BOOLlit *)x_1)->BOOLlit - ((Literal_BOOLlit *)x_2)->BOOLlit;
1990 #line 832 "matchcom.pcc"
1991 } break;
1992 default: { goto L29; } break;
1994 } break;
1995 case a_Literal::tag_CHARlit: {
1996 switch (x_2->tag__) {
1997 case a_Literal::tag_CHARlit: {
1998 #line 831 "matchcom.pcc"
1999 return (int)((Literal_CHARlit *)x_1)->CHARlit - (int)((Literal_CHARlit *)x_2)->CHARlit;
2000 #line 831 "matchcom.pcc"
2001 } break;
2002 default: { goto L29; } break;
2004 } break;
2005 case a_Literal::tag_REALlit: {
2006 switch (x_2->tag__) {
2007 case a_Literal::tag_REALlit: {
2008 #line 830 "matchcom.pcc"
2009 return ((Literal_REALlit *)x_1)->REALlit < ((Literal_REALlit *)x_2)->REALlit ? -1 : (((Literal_REALlit *)x_1)->REALlit > ((Literal_REALlit *)x_2)->REALlit ? 1 : 0);
2010 #line 830 "matchcom.pcc"
2011 } break;
2012 default: { goto L29; } break;
2014 } break;
2015 case a_Literal::tag_STRINGlit: {
2016 switch (x_2->tag__) {
2017 case a_Literal::tag_STRINGlit: {
2018 #line 833 "matchcom.pcc"
2019 return strcmp(((Literal_STRINGlit *)x_1)->STRINGlit,((Literal_STRINGlit *)x_2)->STRINGlit);
2020 #line 833 "matchcom.pcc"
2021 } break;
2022 default: { goto L29; } break;
2024 } break;
2025 case a_Literal::tag_REGEXPlit: {
2026 switch (x_2->tag__) {
2027 case a_Literal::tag_REGEXPlit: {
2028 #line 834 "matchcom.pcc"
2029 return strcmp(((Literal_REGEXPlit *)x_1)->REGEXPlit,((Literal_REGEXPlit *)x_2)->REGEXPlit);
2030 #line 834 "matchcom.pcc"
2031 } break;
2032 default: { goto L29; } break;
2034 } break;
2035 case a_Literal::tag_QUARKlit: {
2036 switch (x_2->tag__) {
2037 case a_Literal::tag_QUARKlit: {
2038 #line 835 "matchcom.pcc"
2039 return strcmp(((Literal_QUARKlit *)x_1)->QUARKlit,((Literal_QUARKlit *)x_2)->QUARKlit);
2040 #line 835 "matchcom.pcc"
2041 } break;
2042 default: { goto L29; } break;
2044 } break;
2045 default: {
2046 switch (x_2->tag__) {
2047 case a_Literal::tag_BIGINTlit: {
2048 #line 836 "matchcom.pcc"
2049 return strcmp(((Literal_BIGINTlit *)x_1)->BIGINTlit,((Literal_BIGINTlit *)x_2)->BIGINTlit);
2050 #line 836 "matchcom.pcc"
2051 } break;
2052 default: { goto L29; } break;
2054 } break;
2057 #line 838 "matchcom.pcc"
2058 #line 838 "matchcom.pcc"
2061 ///////////////////////////////////////////////////////////////////////////////
2063 // Compare two expressions.
2065 ///////////////////////////////////////////////////////////////////////////////
2066 Bool equal (Exp a, Exp b)
2068 #line 846 "matchcom.pcc"
2069 #line 881 "matchcom.pcc"
2071 for (;;) {
2072 if (
2073 #line 847 "matchcom.pcc"
2074 (a == b)
2075 #line 847 "matchcom.pcc"
2078 #line 847 "matchcom.pcc"
2079 return true;
2080 #line 847 "matchcom.pcc"
2081 } else {
2083 if (a) {
2084 switch (a->tag__) {
2085 case a_Exp::tag_LITERALexp: {
2086 if (b) {
2087 switch (b->tag__) {
2088 case a_Exp::tag_LITERALexp: {
2089 #line 848 "matchcom.pcc"
2090 return compare_literals(((Exp_LITERALexp *)a)->LITERALexp,((Exp_LITERALexp *)b)->LITERALexp)==0;
2091 #line 848 "matchcom.pcc"
2092 } break;
2093 case a_Exp::tag_MARKEDexp: {
2094 L31:;
2095 #line 880 "matchcom.pcc"
2096 b = ((Exp_MARKEDexp *)b)->_2;
2097 #line 880 "matchcom.pcc"
2098 } break;
2099 default: {
2100 L32:;
2101 #line 881 "matchcom.pcc"
2102 return false;
2103 #line 881 "matchcom.pcc"
2104 } break;
2106 } else { goto L32; }
2107 } break;
2108 case a_Exp::tag_IDexp: {
2109 if (b) {
2110 switch (b->tag__) {
2111 case a_Exp::tag_IDexp: {
2112 #line 849 "matchcom.pcc"
2113 return ((Exp_IDexp *)a)->IDexp == ((Exp_IDexp *)b)->IDexp;
2114 #line 849 "matchcom.pcc"
2115 } break;
2116 case a_Exp::tag_MARKEDexp: { goto L31; } break;
2117 default: { goto L32; } break;
2119 } else { goto L32; }
2120 } break;
2121 case a_Exp::tag_RELexp: {
2122 if (b) {
2123 switch (b->tag__) {
2124 case a_Exp::tag_RELexp: {
2125 #line 850 "matchcom.pcc"
2126 return same_selectors || ((Exp_RELexp *)a)->RELexp == ((Exp_RELexp *)b)->RELexp;
2127 #line 850 "matchcom.pcc"
2128 } break;
2129 case a_Exp::tag_MARKEDexp: { goto L31; } break;
2130 default: { goto L32; } break;
2132 } else { goto L32; }
2133 } break;
2134 case a_Exp::tag_DOTexp: {
2135 if (b) {
2136 switch (b->tag__) {
2137 case a_Exp::tag_DOTexp: {
2138 #line 851 "matchcom.pcc"
2139 return ((Exp_DOTexp *)a)->_2 == ((Exp_DOTexp *)b)->_2 && equal(((Exp_DOTexp *)a)->_1,((Exp_DOTexp *)b)->_1);
2140 #line 851 "matchcom.pcc"
2141 } break;
2142 case a_Exp::tag_MARKEDexp: { goto L31; } break;
2143 default: { goto L32; } break;
2145 } else { goto L32; }
2146 } break;
2147 case a_Exp::tag_SELECTORexp: {
2148 if (b) {
2149 switch (b->tag__) {
2150 case a_Exp::tag_SELECTORexp: {
2151 #line 853 "matchcom.pcc"
2152 return ((Exp_SELECTORexp *)a)->_2 == ((Exp_SELECTORexp *)b)->_2 && equal(((Exp_SELECTORexp *)a)->_1,((Exp_SELECTORexp *)b)->_1);
2153 #line 853 "matchcom.pcc"
2154 } break;
2155 case a_Exp::tag_MARKEDexp: { goto L31; } break;
2156 default: { goto L32; } break;
2158 } else { goto L32; }
2159 } break;
2160 case a_Exp::tag_DEREFexp: {
2161 if (b) {
2162 switch (b->tag__) {
2163 case a_Exp::tag_DEREFexp: {
2164 #line 854 "matchcom.pcc"
2165 return equal(((Exp_DEREFexp *)a)->DEREFexp,((Exp_DEREFexp *)b)->DEREFexp);
2166 #line 854 "matchcom.pcc"
2167 } break;
2168 case a_Exp::tag_MARKEDexp: { goto L31; } break;
2169 default: { goto L32; } break;
2171 } else { goto L32; }
2172 } break;
2173 case a_Exp::tag_ARROWexp: {
2174 if (b) {
2175 switch (b->tag__) {
2176 case a_Exp::tag_ARROWexp: {
2177 #line 855 "matchcom.pcc"
2178 return ((Exp_ARROWexp *)a)->_2 == ((Exp_ARROWexp *)b)->_2 && equal(((Exp_ARROWexp *)a)->_1,((Exp_ARROWexp *)b)->_1);
2179 #line 855 "matchcom.pcc"
2180 } break;
2181 case a_Exp::tag_MARKEDexp: { goto L31; } break;
2182 default: { goto L32; } break;
2184 } else { goto L32; }
2185 } break;
2186 case a_Exp::tag_INDEXexp: {
2187 if (b) {
2188 switch (b->tag__) {
2189 case a_Exp::tag_INDEXexp: {
2190 #line 856 "matchcom.pcc"
2191 return equal(((Exp_INDEXexp *)a)->_1,((Exp_INDEXexp *)b)->_1) && equal(((Exp_INDEXexp *)a)->_2,((Exp_INDEXexp *)b)->_2);
2192 #line 856 "matchcom.pcc"
2193 } break;
2194 case a_Exp::tag_MARKEDexp: { goto L31; } break;
2195 default: { goto L32; } break;
2197 } else { goto L32; }
2198 } break;
2199 case a_Exp::tag_BINOPexp: {
2200 if (b) {
2201 switch (b->tag__) {
2202 case a_Exp::tag_BINOPexp: {
2203 #line 858 "matchcom.pcc"
2204 return strcmp(((Exp_BINOPexp *)a)->_1,((Exp_BINOPexp *)b)->_1) == 0 && equal(((Exp_BINOPexp *)a)->_2,((Exp_BINOPexp *)b)->_2) && equal(((Exp_BINOPexp *)a)->_3,((Exp_BINOPexp *)b)->_3);
2205 #line 858 "matchcom.pcc"
2206 } break;
2207 case a_Exp::tag_MARKEDexp: { goto L31; } break;
2208 default: { goto L32; } break;
2210 } else { goto L32; }
2211 } break;
2212 case a_Exp::tag_PREFIXexp: {
2213 if (b) {
2214 switch (b->tag__) {
2215 case a_Exp::tag_PREFIXexp: {
2216 #line 859 "matchcom.pcc"
2217 return !strcmp(((Exp_PREFIXexp *)a)->_1,((Exp_PREFIXexp *)b)->_1) && equal(((Exp_PREFIXexp *)a)->_2,((Exp_PREFIXexp *)b)->_2);
2218 #line 859 "matchcom.pcc"
2219 } break;
2220 case a_Exp::tag_MARKEDexp: { goto L31; } break;
2221 default: { goto L32; } break;
2223 } else { goto L32; }
2224 } break;
2225 case a_Exp::tag_POSTFIXexp: {
2226 if (b) {
2227 switch (b->tag__) {
2228 case a_Exp::tag_POSTFIXexp: {
2229 #line 860 "matchcom.pcc"
2230 return !strcmp(((Exp_POSTFIXexp *)a)->_1,((Exp_POSTFIXexp *)b)->_1) && equal(((Exp_POSTFIXexp *)a)->_2,((Exp_POSTFIXexp *)b)->_2);
2231 #line 860 "matchcom.pcc"
2232 } break;
2233 case a_Exp::tag_MARKEDexp: { goto L31; } break;
2234 default: { goto L32; } break;
2236 } else { goto L32; }
2237 } break;
2238 case a_Exp::tag_APPexp: {
2239 if (b) {
2240 switch (b->tag__) {
2241 case a_Exp::tag_APPexp: {
2242 #line 861 "matchcom.pcc"
2243 return equal(((Exp_APPexp *)a)->_1,((Exp_APPexp *)b)->_1) && equal(((Exp_APPexp *)a)->_2,((Exp_APPexp *)b)->_2);
2244 #line 861 "matchcom.pcc"
2245 } break;
2246 case a_Exp::tag_MARKEDexp: { goto L31; } break;
2247 default: { goto L32; } break;
2249 } else { goto L32; }
2250 } break;
2251 case a_Exp::tag_ASSIGNexp: {
2252 if (b) {
2253 switch (b->tag__) {
2254 case a_Exp::tag_ASSIGNexp: {
2255 #line 862 "matchcom.pcc"
2256 return equal(((Exp_ASSIGNexp *)a)->_1,((Exp_ASSIGNexp *)b)->_1) && equal(((Exp_ASSIGNexp *)a)->_2,((Exp_ASSIGNexp *)b)->_2);
2257 #line 862 "matchcom.pcc"
2258 } break;
2259 case a_Exp::tag_MARKEDexp: { goto L31; } break;
2260 default: { goto L32; } break;
2262 } else { goto L32; }
2263 } break;
2264 case a_Exp::tag_IFexp: {
2265 if (b) {
2266 switch (b->tag__) {
2267 case a_Exp::tag_IFexp: {
2268 #line 864 "matchcom.pcc"
2269 return equal(((Exp_IFexp *)a)->_1,((Exp_IFexp *)b)->_1) && equal(((Exp_IFexp *)a)->_2,((Exp_IFexp *)b)->_2) && equal(((Exp_IFexp *)a)->_3,((Exp_IFexp *)b)->_3);
2270 #line 864 "matchcom.pcc"
2271 } break;
2272 case a_Exp::tag_MARKEDexp: { goto L31; } break;
2273 default: { goto L32; } break;
2275 } else { goto L32; }
2276 } break;
2277 case a_Exp::tag_TUPLEexp: {
2278 if (b) {
2279 switch (b->tag__) {
2280 case a_Exp::tag_TUPLEexp: {
2281 #line 865 "matchcom.pcc"
2282 return equal(((Exp_TUPLEexp *)a)->TUPLEexp,((Exp_TUPLEexp *)b)->TUPLEexp);
2283 #line 865 "matchcom.pcc"
2284 } break;
2285 case a_Exp::tag_MARKEDexp: { goto L31; } break;
2286 default: { goto L32; } break;
2288 } else { goto L32; }
2289 } break;
2290 case a_Exp::tag_RECORDexp: {
2291 if (b) {
2292 switch (b->tag__) {
2293 case a_Exp::tag_RECORDexp: {
2294 #line 866 "matchcom.pcc"
2295 return equal(((Exp_RECORDexp *)a)->RECORDexp,((Exp_RECORDexp *)b)->RECORDexp);
2296 #line 866 "matchcom.pcc"
2297 } break;
2298 case a_Exp::tag_MARKEDexp: { goto L31; } break;
2299 default: { goto L32; } break;
2301 } else { goto L32; }
2302 } break;
2303 case a_Exp::tag_LISTexp: {
2304 if (b) {
2305 switch (b->tag__) {
2306 case a_Exp::tag_LISTexp: {
2307 #line 869 "matchcom.pcc"
2308 return ((Exp_LISTexp *)a)->_1 == ((Exp_LISTexp *)b)->_1 && equal(((Exp_LISTexp *)a)->_3,((Exp_LISTexp *)b)->_3) && equal(((Exp_LISTexp *)a)->_4,((Exp_LISTexp *)b)->_4);
2309 #line 869 "matchcom.pcc"
2310 } break;
2311 case a_Exp::tag_MARKEDexp: { goto L31; } break;
2312 default: { goto L32; } break;
2314 } else { goto L32; }
2315 } break;
2316 case a_Exp::tag_CONSexp: {
2317 if (b) {
2318 switch (b->tag__) {
2319 case a_Exp::tag_CONSexp: {
2320 #line 870 "matchcom.pcc"
2321 return ((Exp_CONSexp *)a)->_1 == ((Exp_CONSexp *)b)->_1 && equal(((Exp_CONSexp *)a)->_2,((Exp_CONSexp *)b)->_2) && equal(((Exp_CONSexp *)a)->_3,((Exp_CONSexp *)b)->_3);
2322 #line 870 "matchcom.pcc"
2323 } break;
2324 case a_Exp::tag_MARKEDexp: { goto L31; } break;
2325 default: { goto L32; } break;
2327 } else { goto L32; }
2328 } break;
2329 case a_Exp::tag_EQexp: {
2330 if (b) {
2331 switch (b->tag__) {
2332 case a_Exp::tag_EQexp: {
2333 #line 871 "matchcom.pcc"
2334 return equal(((Exp_EQexp *)a)->_2,((Exp_EQexp *)b)->_2) && equal(((Exp_EQexp *)a)->_3,((Exp_EQexp *)b)->_3);
2335 #line 871 "matchcom.pcc"
2336 } break;
2337 case a_Exp::tag_MARKEDexp: { goto L31; } break;
2338 default: { goto L32; } break;
2340 } else { goto L32; }
2341 } break;
2342 case a_Exp::tag_UNIFYexp: {
2343 if (b) {
2344 switch (b->tag__) {
2345 case a_Exp::tag_UNIFYexp: {
2346 #line 872 "matchcom.pcc"
2347 return equal(((Exp_UNIFYexp *)a)->_2,((Exp_UNIFYexp *)b)->_2) && equal(((Exp_UNIFYexp *)a)->_3,((Exp_UNIFYexp *)b)->_3);
2348 #line 872 "matchcom.pcc"
2349 } break;
2350 case a_Exp::tag_MARKEDexp: { goto L31; } break;
2351 default: { goto L32; } break;
2353 } else { goto L32; }
2354 } break;
2355 case a_Exp::tag_LTexp: {
2356 if (b) {
2357 switch (b->tag__) {
2358 case a_Exp::tag_LTexp: {
2359 #line 873 "matchcom.pcc"
2360 return equal(((Exp_LTexp *)a)->_2,((Exp_LTexp *)b)->_2) && equal(((Exp_LTexp *)a)->_3,((Exp_LTexp *)b)->_3);
2361 #line 873 "matchcom.pcc"
2362 } break;
2363 case a_Exp::tag_MARKEDexp: { goto L31; } break;
2364 default: { goto L32; } break;
2366 } else { goto L32; }
2367 } break;
2368 case a_Exp::tag_HASHexp: {
2369 if (b) {
2370 switch (b->tag__) {
2371 case a_Exp::tag_HASHexp: {
2372 #line 874 "matchcom.pcc"
2373 a = ((Exp_HASHexp *)a)->_2; b = ((Exp_HASHexp *)b)->_2;
2374 #line 874 "matchcom.pcc"
2375 } break;
2376 case a_Exp::tag_MARKEDexp: { goto L31; } break;
2377 default: { goto L32; } break;
2379 } else { goto L32; }
2380 } break;
2381 case a_Exp::tag_THISCOSTexp: {
2382 if (b) {
2383 switch (b->tag__) {
2384 case a_Exp::tag_THISCOSTexp: {
2385 #line 875 "matchcom.pcc"
2386 return true;
2387 #line 875 "matchcom.pcc"
2388 } break;
2389 case a_Exp::tag_MARKEDexp: { goto L31; } break;
2390 default: { goto L32; } break;
2392 } else { goto L32; }
2393 } break;
2394 case a_Exp::tag_COSTexp: {
2395 if (b) {
2396 switch (b->tag__) {
2397 case a_Exp::tag_COSTexp: {
2398 #line 876 "matchcom.pcc"
2399 return ((Exp_COSTexp *)a)->COSTexp == ((Exp_COSTexp *)b)->COSTexp;
2400 #line 876 "matchcom.pcc"
2401 } break;
2402 case a_Exp::tag_MARKEDexp: { goto L31; } break;
2403 default: { goto L32; } break;
2405 } else { goto L32; }
2406 } break;
2407 case a_Exp::tag_THISSYNexp: {
2408 if (b) {
2409 switch (b->tag__) {
2410 case a_Exp::tag_THISSYNexp: {
2411 #line 878 "matchcom.pcc"
2412 return ((Exp_THISSYNexp *)a)->_1 == ((Exp_THISSYNexp *)b)->_1;
2413 #line 878 "matchcom.pcc"
2414 } break;
2415 case a_Exp::tag_MARKEDexp: { goto L31; } break;
2416 default: { goto L32; } break;
2418 } else { goto L32; }
2419 } break;
2420 case a_Exp::tag_SYNexp: {
2421 if (b) {
2422 switch (b->tag__) {
2423 case a_Exp::tag_SYNexp: {
2424 #line 877 "matchcom.pcc"
2425 return ((Exp_SYNexp *)a)->_1 == ((Exp_SYNexp *)b)->_1 && ((Exp_SYNexp *)a)->_2 == ((Exp_SYNexp *)b)->_2;
2426 #line 877 "matchcom.pcc"
2427 } break;
2428 case a_Exp::tag_MARKEDexp: { goto L31; } break;
2429 default: { goto L32; } break;
2431 } else { goto L32; }
2432 } break;
2433 case a_Exp::tag_SENDexp: {
2434 if (b) {
2435 switch (b->tag__) {
2436 case a_Exp::tag_SENDexp: {
2437 #line 867 "matchcom.pcc"
2438 return ((Exp_SENDexp *)a)->_1 == ((Exp_SENDexp *)b)->_1 && equal(((Exp_SENDexp *)a)->_2,((Exp_SENDexp *)b)->_2);
2439 #line 867 "matchcom.pcc"
2440 } break;
2441 case a_Exp::tag_MARKEDexp: { goto L31; } break;
2442 default: { goto L32; } break;
2444 } else { goto L32; }
2445 } break;
2446 case a_Exp::tag_MARKEDexp: {
2447 #line 879 "matchcom.pcc"
2448 a = ((Exp_MARKEDexp *)a)->_2;
2449 #line 879 "matchcom.pcc"
2450 } break;
2451 default: {
2452 L33:;
2453 if (b) {
2454 switch (b->tag__) {
2455 case a_Exp::tag_MARKEDexp: { goto L31; } break;
2456 default: { goto L32; } break;
2458 } else { goto L32; }
2459 } break;
2461 } else { goto L33; }
2465 #line 882 "matchcom.pcc"
2466 #line 882 "matchcom.pcc"
2470 ///////////////////////////////////////////////////////////////////////////////
2472 // Equality between two expression lists
2474 ///////////////////////////////////////////////////////////////////////////////
2475 Bool equal (Exps a, Exps b)
2477 #line 891 "matchcom.pcc"
2478 #line 893 "matchcom.pcc"
2480 for (;;) {
2481 if (a) {
2482 if (b) {
2483 #line 893 "matchcom.pcc"
2484 if (! equal(a->_1, b->_1)) return false; a = a->_2; b = b->_2;
2485 #line 893 "matchcom.pcc"
2486 } else { goto L34; }
2487 } else { goto L34; }
2489 L34:;
2491 #line 894 "matchcom.pcc"
2492 #line 894 "matchcom.pcc"
2494 return a ==
2495 #line 895 "matchcom.pcc"
2496 #line 895 "matchcom.pcc"
2497 nil_1_
2498 #line 895 "matchcom.pcc"
2499 #line 895 "matchcom.pcc"
2500 && b ==
2501 #line 895 "matchcom.pcc"
2502 #line 895 "matchcom.pcc"
2503 nil_1_
2504 #line 895 "matchcom.pcc"
2505 #line 895 "matchcom.pcc"
2509 ///////////////////////////////////////////////////////////////////////////////
2511 // Equality between two labeled expression lists
2513 ///////////////////////////////////////////////////////////////////////////////
2514 Bool equal (LabExps a, LabExps b)
2516 #line 904 "matchcom.pcc"
2517 #line 906 "matchcom.pcc"
2519 for (;;) {
2520 if (a) {
2521 if (b) {
2522 #line 906 "matchcom.pcc"
2523 if (! equal(a->_1.exp, b->_1.exp)) return false; a = a->_2; b = b->_2;
2524 #line 906 "matchcom.pcc"
2525 } else { goto L35; }
2526 } else { goto L35; }
2528 L35:;
2530 #line 907 "matchcom.pcc"
2531 #line 907 "matchcom.pcc"
2533 return a ==
2534 #line 908 "matchcom.pcc"
2535 #line 908 "matchcom.pcc"
2536 nil_1_
2537 #line 908 "matchcom.pcc"
2538 #line 908 "matchcom.pcc"
2539 && b ==
2540 #line 908 "matchcom.pcc"
2541 #line 908 "matchcom.pcc"
2542 nil_1_
2543 #line 908 "matchcom.pcc"
2544 #line 908 "matchcom.pcc"
2548 ///////////////////////////////////////////////////////////////////////////////
2550 // Check to see if we have a regular expression.
2552 ///////////////////////////////////////////////////////////////////////////////
2553 Bool has_regexp(int n, Literal l[])
2554 { for (int i = n - 1; i >= 0; i--)
2556 #line 918 "matchcom.pcc"
2557 #line 918 "matchcom.pcc"
2559 Literal _V5 = l[i];
2560 switch (_V5->tag__) {
2561 case a_Literal::tag_REGEXPlit: {
2562 #line 918 "matchcom.pcc"
2563 return true;
2564 #line 918 "matchcom.pcc"
2565 } break;
2566 default: {
2567 #line 918 "matchcom.pcc"
2568 /* skip */
2569 #line 918 "matchcom.pcc"
2570 } break;
2573 #line 918 "matchcom.pcc"
2574 #line 918 "matchcom.pcc"
2576 return false;
2579 ///////////////////////////////////////////////////////////////////////////////
2581 // Convert all string literals into regular expression literals.
2583 ///////////////////////////////////////////////////////////////////////////////
2584 void convert_regexp(int n, Literal l[])
2585 { for (int i = n-1; i >= 0; i--)
2587 #line 929 "matchcom.pcc"
2588 #line 931 "matchcom.pcc"
2590 Literal _V6 = l[i];
2591 switch (_V6->tag__) {
2592 case a_Literal::tag_STRINGlit: {
2593 #line 930 "matchcom.pcc"
2594 l[i] = REGEXPlit(convert_regexp(((Literal_STRINGlit *)_V6)->STRINGlit));
2595 #line 930 "matchcom.pcc"
2596 } break;
2597 default: {
2598 #line 931 "matchcom.pcc"
2599 /* skip */
2600 #line 931 "matchcom.pcc"
2601 } break;
2604 #line 932 "matchcom.pcc"
2605 #line 932 "matchcom.pcc"
2610 ///////////////////////////////////////////////////////////////////////////////
2612 // Compose two matching trees.
2614 ///////////////////////////////////////////////////////////////////////////////
2615 Match MatchCompiler::compose (Match a, Match b)
2617 #line 942 "matchcom.pcc"
2618 #line 981 "matchcom.pcc"
2620 if (boxed(a)) {
2621 switch (a->tag__) {
2622 case a_Match::tag_SUCCESSESmatch: {
2623 if (boxed(b)) {
2624 switch (b->tag__) {
2625 case a_Match::tag_SUCCESSESmatch: {
2626 #line 944 "matchcom.pcc"
2627 BitSet * c = new (mem_pool, ((Match_SUCCESSESmatch *)a)->_1) BitSet;
2628 c->Union(*((Match_SUCCESSESmatch *)a)->_2,*((Match_SUCCESSESmatch *)b)->_2);
2629 return SUCCESSESmatch(((Match_SUCCESSESmatch *)a)->_1,c,((Match_SUCCESSESmatch *)a)->_3);
2631 #line 947 "matchcom.pcc"
2632 } break;
2633 default: {
2634 L36:;
2635 #line 981 "matchcom.pcc"
2636 /* skip */
2637 #line 981 "matchcom.pcc"
2638 } break;
2640 } else { goto L36; }
2641 } break;
2642 case a_Match::tag_COSTmatch: {
2643 if (boxed(b)) {
2644 switch (b->tag__) {
2645 case a_Match::tag_COSTmatch: {
2646 #line 950 "matchcom.pcc"
2647 register BitSet * set = new (mem_pool, ((Match_COSTmatch *)a)->_1) BitSet;
2648 set->Union (*((Match_COSTmatch *)a)->_3, *((Match_COSTmatch *)b)->_3);
2649 register int min_cost = MAX_COST;
2650 register int r;
2652 // Find the minimal known cost
2653 for (r = 0; r < ((Match_COSTmatch *)a)->_1; r++) {
2654 if (set->contains(r)) {
2656 #line 958 "matchcom.pcc"
2657 #line 962 "matchcom.pcc"
2659 Cost _V7 = ((Match_COSTmatch *)a)->_2[r];
2660 if (_V7) {
2661 if (untagp(_V7)) {
2663 if (
2664 #line 960 "matchcom.pcc"
2665 (((Cost_INTcost *)derefp(_V7))->INTcost < min_cost)
2666 #line 960 "matchcom.pcc"
2669 #line 960 "matchcom.pcc"
2670 min_cost = ((Cost_INTcost *)derefp(_V7))->INTcost;
2671 #line 960 "matchcom.pcc"
2672 } else {
2674 L37:; }
2675 } else {
2676 goto L37; }
2677 } else {
2678 #line 959 "matchcom.pcc"
2679 min_cost = 0;
2680 #line 959 "matchcom.pcc"
2683 #line 962 "matchcom.pcc"
2684 #line 962 "matchcom.pcc"
2689 // Prune away all the rules with higher or equal cost than min_cost.
2690 Bool found = false;
2691 for (r = 0; r < ((Match_COSTmatch *)a)->_1; r++) {
2692 if (set->contains(r)) {
2694 #line 970 "matchcom.pcc"
2695 #line 975 "matchcom.pcc"
2697 Cost _V8 = ((Match_COSTmatch *)a)->_2[r];
2698 if (_V8) {
2699 if (untagp(_V8)) {
2701 #line 972 "matchcom.pcc"
2702 if (((Cost_INTcost *)derefp(_V8))->INTcost > min_cost || found) set->remove(r);
2703 found = true;
2704 #line 973 "matchcom.pcc"
2705 } else {
2707 } else {
2708 #line 971 "matchcom.pcc"
2709 if (! found) set->remove(r); found = true;
2710 #line 971 "matchcom.pcc"
2713 #line 975 "matchcom.pcc"
2714 #line 975 "matchcom.pcc"
2719 return COSTmatch (((Match_COSTmatch *)a)->_1, ((Match_COSTmatch *)a)->_2, set, ((Match_COSTmatch *)a)->_4);
2721 #line 980 "matchcom.pcc"
2722 } break;
2723 default: { goto L36; } break;
2725 } else { goto L36; }
2726 } break;
2727 default: { goto L36; } break;
2729 } else { goto L36; }
2731 #line 982 "matchcom.pcc"
2732 #line 982 "matchcom.pcc"
2736 #line 984 "matchcom.pcc"
2737 #line 1004 "matchcom.pcc"
2739 if (boxed(a)) {
2740 switch (a->tag__) {
2741 case a_Match::tag_SUCCESSmatch: {
2742 #line 988 "matchcom.pcc"
2743 return a;
2744 #line 988 "matchcom.pcc"
2745 } break;
2746 case a_Match::tag_GUARDmatch: {
2747 #line 990 "matchcom.pcc"
2748 return GUARDmatch(((Match_GUARDmatch *)a)->_1,merge(((Match_GUARDmatch *)a)->_2,b),merge(((Match_GUARDmatch *)a)->_3,b));
2749 #line 990 "matchcom.pcc"
2750 } break;
2751 case a_Match::tag_LITERALmatch: {
2752 #line 992 "matchcom.pcc"
2753 Match * br = Matches(((Match_LITERALmatch *)a)->_4);
2754 for (int i = ((Match_LITERALmatch *)a)->_4 - 1; i >= 0; i--) br[i] = merge(((Match_LITERALmatch *)a)->_5[i],b);
2755 return LITERALmatch(((Match_LITERALmatch *)a)->_1,((Match_LITERALmatch *)a)->_2,((Match_LITERALmatch *)a)->_3,((Match_LITERALmatch *)a)->_4,br,merge(((Match_LITERALmatch *)a)->_6,b));
2757 #line 995 "matchcom.pcc"
2758 } break;
2759 case a_Match::tag_RANGEmatch: {
2760 #line 1002 "matchcom.pcc"
2761 return RANGEmatch(((Match_RANGEmatch *)a)->_1,((Match_RANGEmatch *)a)->_2,((Match_RANGEmatch *)a)->_3,((Match_RANGEmatch *)a)->_4,merge(((Match_RANGEmatch *)a)->_5,b),merge(((Match_RANGEmatch *)a)->_6,b));
2762 #line 1002 "matchcom.pcc"
2763 } break;
2764 case a_Match::tag_CONSmatch: {
2765 #line 997 "matchcom.pcc"
2766 Match * br = Matches(((Match_CONSmatch *)a)->_5);
2767 for (int i = ((Match_CONSmatch *)a)->_5 - 1; i >= 0; i--) br[i] = merge(((Match_CONSmatch *)a)->_6[i],b);
2768 return CONSmatch(((Match_CONSmatch *)a)->_1,((Match_CONSmatch *)a)->_2,((Match_CONSmatch *)a)->_3,((Match_CONSmatch *)a)->_4,((Match_CONSmatch *)a)->_5,br,merge(((Match_CONSmatch *)a)->_7,b));
2770 #line 1000 "matchcom.pcc"
2771 } break;
2772 case a_Match::tag_BACKEDGEmatch: {
2773 #line 987 "matchcom.pcc"
2774 return a;
2775 #line 987 "matchcom.pcc"
2776 } break;
2777 case a_Match::tag_SUCCESSESmatch:
2778 case a_Match::tag_COSTmatch: {
2779 #line 989 "matchcom.pcc"
2780 return compose(b,a);
2781 #line 989 "matchcom.pcc"
2782 } break;
2783 default: {
2784 #line 1004 "matchcom.pcc"
2785 bug("MatchCompiler::compose: %m, %m",a,b); return a;
2786 #line 1004 "matchcom.pcc"
2787 } break;
2789 } else {
2790 if (a) {
2792 #line 986 "matchcom.pcc"
2793 return a;
2794 #line 986 "matchcom.pcc"
2795 } else {
2797 #line 985 "matchcom.pcc"
2798 return b;
2799 #line 985 "matchcom.pcc"
2803 #line 1005 "matchcom.pcc"
2804 #line 1005 "matchcom.pcc"
2808 ///////////////////////////////////////////////////////////////////////////////
2810 // Merge two matching trees.
2812 ///////////////////////////////////////////////////////////////////////////////
2813 Match MatchCompiler::merge (Match a, Match b)
2815 #line 1014 "matchcom.pcc"
2816 #line 1024 "matchcom.pcc"
2818 if (boxed(a)) {
2819 switch (a->tag__) {
2820 case a_Match::tag_SUCCESSmatch: {
2821 if (boxed(b)) {
2822 L38:;
2823 #line 1017 "matchcom.pcc"
2824 return a;
2825 #line 1017 "matchcom.pcc"
2826 } else {
2827 if (b) {
2828 goto L38; } else {
2830 L39:;
2831 #line 1016 "matchcom.pcc"
2832 return a;
2833 #line 1016 "matchcom.pcc"
2836 } break;
2837 case a_Match::tag_SUCCESSESmatch:
2838 case a_Match::tag_COSTmatch: {
2839 if (boxed(b)) {
2840 L40:;
2841 #line 1022 "matchcom.pcc"
2842 return compose(a,b);
2843 #line 1022 "matchcom.pcc"
2844 } else {
2845 if (b) {
2846 goto L40; } else {
2847 goto L39; }
2849 } break;
2850 default: {
2851 L41:;
2852 if (boxed(b)) {
2853 switch (b->tag__) {
2854 case a_Match::tag_SUCCESSmatch:
2855 case a_Match::tag_SUCCESSESmatch:
2856 case a_Match::tag_COSTmatch: { goto L40; } break;
2857 default: {
2858 L42:; } break;
2860 } else {
2861 if (b) {
2862 goto L42; } else {
2863 goto L39; }
2865 } break;
2867 } else {
2868 if (a) {
2869 goto L41; } else {
2871 #line 1015 "matchcom.pcc"
2872 return b;
2873 #line 1015 "matchcom.pcc"
2877 #line 1024 "matchcom.pcc"
2878 #line 1024 "matchcom.pcc"
2882 #line 1026 "matchcom.pcc"
2883 #line 1097 "matchcom.pcc"
2885 CompareResult _V9 = compare_pos(get_pos(a),get_pos(b));
2886 switch (_V9) {
2887 case LESS: {
2888 if (boxed(a)) {
2889 switch (a->tag__) {
2890 case a_Match::tag_GUARDmatch: {
2891 #line 1074 "matchcom.pcc"
2892 return GUARDmatch(((Match_GUARDmatch *)a)->_1, merge(((Match_GUARDmatch *)a)->_2,b), merge(((Match_GUARDmatch *)a)->_3,b));
2893 #line 1074 "matchcom.pcc"
2894 } break;
2895 case a_Match::tag_LITERALmatch: {
2896 #line 1076 "matchcom.pcc"
2897 Match * br = Matches(((Match_LITERALmatch *)a)->_4);
2898 for (int i = ((Match_LITERALmatch *)a)->_4 - 1; i >= 0; i--) br[i] = merge(((Match_LITERALmatch *)a)->_5[i],b);
2899 return LITERALmatch(((Match_LITERALmatch *)a)->_1,((Match_LITERALmatch *)a)->_2,((Match_LITERALmatch *)a)->_3,((Match_LITERALmatch *)a)->_4,br,merge(((Match_LITERALmatch *)a)->_6,b));
2901 #line 1079 "matchcom.pcc"
2902 } break;
2903 case a_Match::tag_CONSmatch: {
2904 #line 1081 "matchcom.pcc"
2905 Match * br = Matches(((Match_CONSmatch *)a)->_5);
2906 for (int i = ((Match_CONSmatch *)a)->_5 - 1; i >= 0; i--) br[i] = merge(((Match_CONSmatch *)a)->_6[i],b);
2907 return CONSmatch (((Match_CONSmatch *)a)->_1,((Match_CONSmatch *)a)->_2,((Match_CONSmatch *)a)->_3,((Match_CONSmatch *)a)->_4,((Match_CONSmatch *)a)->_5,br,merge(((Match_CONSmatch *)a)->_7,b));
2909 #line 1084 "matchcom.pcc"
2910 } break;
2911 default: {
2912 L43:;
2913 #line 1097 "matchcom.pcc"
2914 return compose(a,b);
2915 #line 1097 "matchcom.pcc"
2916 } break;
2918 } else { goto L43; }
2919 } break;
2920 case SAME: {
2921 if (boxed(a)) {
2922 switch (a->tag__) {
2923 case a_Match::tag_GUARDmatch: {
2924 if (boxed(b)) {
2925 switch (b->tag__) {
2926 case a_Match::tag_GUARDmatch: {
2927 #line 1028 "matchcom.pcc"
2928 if (equal(((Match_GUARDmatch *)a)->_1,((Match_GUARDmatch *)b)->_1))
2929 return GUARDmatch(((Match_GUARDmatch *)a)->_1,merge(((Match_GUARDmatch *)a)->_2,((Match_GUARDmatch *)b)->_2), merge(((Match_GUARDmatch *)a)->_3,((Match_GUARDmatch *)b)->_3));
2930 else return GUARDmatch(((Match_GUARDmatch *)a)->_1,merge(((Match_GUARDmatch *)a)->_2,b),merge(((Match_GUARDmatch *)a)->_3,b));
2932 #line 1031 "matchcom.pcc"
2933 } break;
2934 default: { goto L43; } break;
2936 } else { goto L43; }
2937 } break;
2938 case a_Match::tag_LITERALmatch: {
2939 if (boxed(b)) {
2940 switch (b->tag__) {
2941 case a_Match::tag_LITERALmatch: {
2942 #line 1041 "matchcom.pcc"
2943 int i, n = ((Match_LITERALmatch *)a)->_4 + ((Match_LITERALmatch *)b)->_4;
2944 Match * br = Matches(n);
2945 Literal * ls = Literals(n);
2947 if (has_regexp(((Match_LITERALmatch *)a)->_4,((Match_LITERALmatch *)a)->_3) || has_regexp(((Match_LITERALmatch *)b)->_4,((Match_LITERALmatch *)b)->_3)) {
2948 for (i = 0; i < ((Match_LITERALmatch *)a)->_4; i++) { br[i] = ((Match_LITERALmatch *)a)->_5[i]; ls[i] = ((Match_LITERALmatch *)a)->_3[i]; }
2949 for (i = 0; i < ((Match_LITERALmatch *)b)->_4; i++) { br[((Match_LITERALmatch *)a)->_4+i] = ((Match_LITERALmatch *)b)->_5[i]; ls[((Match_LITERALmatch *)a)->_4+i] = ((Match_LITERALmatch *)b)->_3[i]; }
2950 convert_regexp(n,ls);
2951 } else {
2952 // merge and eliminate duplicates
2953 int i, j, k;
2954 for (i = 0, j = 0, k = 0; i < ((Match_LITERALmatch *)a)->_4 && j < ((Match_LITERALmatch *)b)->_4; )
2955 { int dir = compare_literals(((Match_LITERALmatch *)a)->_3[i],((Match_LITERALmatch *)b)->_3[j]);
2956 if (dir == 0)
2957 { ls[k] = ((Match_LITERALmatch *)a)->_3[i]; br[k] = merge(((Match_LITERALmatch *)a)->_5[i],((Match_LITERALmatch *)b)->_5[j]); i++; j++; }
2958 else if (dir < 0)
2959 { ls[k] = ((Match_LITERALmatch *)a)->_3[i]; br[k] = merge(((Match_LITERALmatch *)a)->_5[i],((Match_LITERALmatch *)b)->_6); i++; }
2960 else
2961 { ls[k] = ((Match_LITERALmatch *)b)->_3[j]; br[k] = merge(((Match_LITERALmatch *)a)->_6,((Match_LITERALmatch *)b)->_5[j]); j++; }
2962 k++;
2964 while (i < ((Match_LITERALmatch *)a)->_4) { ls[k] = ((Match_LITERALmatch *)a)->_3[i]; br[k++] = merge(((Match_LITERALmatch *)a)->_5[i++],((Match_LITERALmatch *)b)->_6); }
2965 while (j < ((Match_LITERALmatch *)b)->_4) { ls[k] = ((Match_LITERALmatch *)b)->_3[j]; br[k++] = merge(((Match_LITERALmatch *)a)->_6,((Match_LITERALmatch *)b)->_5[j++]); }
2966 n = k;
2968 return LITERALmatch(((Match_LITERALmatch *)a)->_1,((Match_LITERALmatch *)a)->_2,ls,n,br,merge(((Match_LITERALmatch *)a)->_6,((Match_LITERALmatch *)b)->_6));
2970 #line 1067 "matchcom.pcc"
2971 } break;
2972 default: { goto L43; } break;
2974 } else { goto L43; }
2975 } break;
2976 case a_Match::tag_RANGEmatch: {
2977 if (boxed(b)) {
2978 switch (b->tag__) {
2979 case a_Match::tag_RANGEmatch: {
2980 #line 1033 "matchcom.pcc"
2981 if (((Match_RANGEmatch *)a)->_3 == 0 && ((Match_RANGEmatch *)a)->_4 == INT_MAX)
2982 return merge(((Match_RANGEmatch *)a)->_5,b);
2983 else if (((Match_RANGEmatch *)a)->_3 <= ((Match_RANGEmatch *)b)->_3 && ((Match_RANGEmatch *)a)->_4 >= ((Match_RANGEmatch *)b)->_4)
2984 return RANGEmatch(((Match_RANGEmatch *)a)->_1,((Match_RANGEmatch *)a)->_2,((Match_RANGEmatch *)a)->_3,((Match_RANGEmatch *)a)->_4,merge(((Match_RANGEmatch *)a)->_5,((Match_RANGEmatch *)b)->_5),merge(((Match_RANGEmatch *)a)->_6,((Match_RANGEmatch *)b)->_6));
2985 else
2986 return RANGEmatch(((Match_RANGEmatch *)a)->_1,((Match_RANGEmatch *)b)->_2,((Match_RANGEmatch *)a)->_3,((Match_RANGEmatch *)a)->_4,merge(((Match_RANGEmatch *)a)->_5,b),merge(((Match_RANGEmatch *)a)->_6,b));
2988 #line 1039 "matchcom.pcc"
2989 } break;
2990 default: { goto L43; } break;
2992 } else { goto L43; }
2993 } break;
2994 case a_Match::tag_CONSmatch: {
2995 if (boxed(b)) {
2996 switch (b->tag__) {
2997 case a_Match::tag_CONSmatch: {
2998 #line 1069 "matchcom.pcc"
2999 Match * br = Matches(((Match_CONSmatch *)a)->_5);
3000 for (int i = ((Match_CONSmatch *)a)->_5 - 1; i >= 0; i--) br[i] = merge(((Match_CONSmatch *)a)->_6[i],((Match_CONSmatch *)b)->_6[i]);
3001 return CONSmatch (((Match_CONSmatch *)a)->_1,((Match_CONSmatch *)a)->_2,((Match_CONSmatch *)a)->_3,((Match_CONSmatch *)a)->_4,((Match_CONSmatch *)a)->_5,br,merge(((Match_CONSmatch *)a)->_7,((Match_CONSmatch *)b)->_7));
3003 #line 1072 "matchcom.pcc"
3004 } break;
3005 default: { goto L43; } break;
3007 } else { goto L43; }
3008 } break;
3009 default: { goto L43; } break;
3011 } else { goto L43; }
3012 } break;
3013 case MORE: {
3014 if (boxed(b)) {
3015 switch (b->tag__) {
3016 case a_Match::tag_GUARDmatch: {
3017 #line 1086 "matchcom.pcc"
3018 return GUARDmatch(((Match_GUARDmatch *)b)->_1, merge(a,((Match_GUARDmatch *)b)->_2), merge(a,((Match_GUARDmatch *)b)->_3));
3019 #line 1086 "matchcom.pcc"
3020 } break;
3021 case a_Match::tag_LITERALmatch: {
3022 #line 1088 "matchcom.pcc"
3023 Match * br = Matches(((Match_LITERALmatch *)b)->_4);
3024 for (int i = ((Match_LITERALmatch *)b)->_4 - 1; i >= 0; i--) br[i] = merge(a,((Match_LITERALmatch *)b)->_5[i]);
3025 return LITERALmatch(((Match_LITERALmatch *)b)->_1,((Match_LITERALmatch *)b)->_2,((Match_LITERALmatch *)b)->_3,((Match_LITERALmatch *)b)->_4,br,merge(a,((Match_LITERALmatch *)b)->_6));
3027 #line 1091 "matchcom.pcc"
3028 } break;
3029 case a_Match::tag_CONSmatch: {
3030 #line 1093 "matchcom.pcc"
3031 Match * br = Matches(((Match_CONSmatch *)b)->_5);
3032 for (int i = ((Match_CONSmatch *)b)->_5 - 1; i >= 0; i--) br[i] = merge(a,((Match_CONSmatch *)b)->_6[i]);
3033 return CONSmatch (((Match_CONSmatch *)b)->_1,((Match_CONSmatch *)b)->_2,((Match_CONSmatch *)b)->_3,((Match_CONSmatch *)b)->_4,((Match_CONSmatch *)b)->_5,br,merge(a,((Match_CONSmatch *)b)->_7));
3035 #line 1096 "matchcom.pcc"
3036 } break;
3037 default: { goto L43; } break;
3039 } else { goto L43; }
3040 } break;
3041 default: { goto L43; } break;
3044 #line 1098 "matchcom.pcc"
3045 #line 1098 "matchcom.pcc"
3049 ///////////////////////////////////////////////////////////////////////////////
3051 // Equality between two matching tree.
3053 ///////////////////////////////////////////////////////////////////////////////
3054 Bool match_equal (HashTable::Key a, HashTable::Key b)
3056 #line 1107 "matchcom.pcc"
3057 #line 1132 "matchcom.pcc"
3059 Match _V10 = Match(a);
3060 Match _V11 = Match(b);
3061 if (boxed(_V10)) {
3062 switch (_V10->tag__) {
3063 case a_Match::tag_SUCCESSmatch: {
3064 if (boxed(_V11)) {
3065 switch (_V11->tag__) {
3066 case a_Match::tag_SUCCESSmatch: {
3067 #line 1109 "matchcom.pcc"
3068 return a == b;
3069 #line 1109 "matchcom.pcc"
3070 } break;
3071 default: {
3072 L44:;
3073 #line 1132 "matchcom.pcc"
3074 return false;
3075 #line 1132 "matchcom.pcc"
3076 } break;
3078 } else { goto L44; }
3079 } break;
3080 case a_Match::tag_SUCCESSESmatch: {
3081 if (boxed(_V11)) {
3082 switch (_V11->tag__) {
3083 case a_Match::tag_SUCCESSESmatch: {
3084 #line 1110 "matchcom.pcc"
3085 return equal(((Match_SUCCESSESmatch *)_V10)->_2,((Match_SUCCESSESmatch *)_V11)->_2);
3086 #line 1110 "matchcom.pcc"
3087 } break;
3088 default: { goto L44; } break;
3090 } else { goto L44; }
3091 } break;
3092 case a_Match::tag_COSTmatch: {
3093 if (boxed(_V11)) {
3094 switch (_V11->tag__) {
3095 case a_Match::tag_COSTmatch: {
3096 #line 1111 "matchcom.pcc"
3097 return equal(((Match_COSTmatch *)_V10)->_3,((Match_COSTmatch *)_V11)->_3);
3098 #line 1111 "matchcom.pcc"
3099 } break;
3100 default: { goto L44; } break;
3102 } else { goto L44; }
3103 } break;
3104 case a_Match::tag_GUARDmatch: {
3105 if (boxed(_V11)) {
3106 switch (_V11->tag__) {
3107 case a_Match::tag_GUARDmatch: {
3108 #line 1113 "matchcom.pcc"
3109 return equal(((Match_GUARDmatch *)_V10)->_1,((Match_GUARDmatch *)_V11)->_1) && ((Match_GUARDmatch *)_V10)->_2 == ((Match_GUARDmatch *)_V11)->_2 && ((Match_GUARDmatch *)_V10)->_3 == ((Match_GUARDmatch *)_V11)->_3;
3110 #line 1113 "matchcom.pcc"
3111 } break;
3112 default: { goto L44; } break;
3114 } else { goto L44; }
3115 } break;
3116 case a_Match::tag_LITERALmatch: {
3117 if (boxed(_V11)) {
3118 switch (_V11->tag__) {
3119 case a_Match::tag_LITERALmatch: {
3120 if (
3121 #line 1118 "matchcom.pcc"
3122 (((Match_LITERALmatch *)_V10)->_4 == ((Match_LITERALmatch *)_V11)->_4)
3123 #line 1118 "matchcom.pcc"
3126 #line 1119 "matchcom.pcc"
3127 if (compare_pos(((Match_LITERALmatch *)_V10)->_1,((Match_LITERALmatch *)_V11)->_1) != SAME) return false;
3128 for (int k = ((Match_LITERALmatch *)_V10)->_4-1; k >= 0; k--) if (((Match_LITERALmatch *)_V10)->_5[k] != ((Match_LITERALmatch *)_V11)->_5[k]) return false;
3129 return ((Match_LITERALmatch *)_V10)->_6 == ((Match_LITERALmatch *)_V11)->_6;
3131 #line 1122 "matchcom.pcc"
3132 } else {
3133 goto L44; }
3134 } break;
3135 default: { goto L44; } break;
3137 } else { goto L44; }
3138 } break;
3139 case a_Match::tag_RANGEmatch: {
3140 if (boxed(_V11)) {
3141 switch (_V11->tag__) {
3142 case a_Match::tag_RANGEmatch: {
3143 #line 1129 "matchcom.pcc"
3144 return compare_pos(((Match_RANGEmatch *)_V10)->_1,((Match_RANGEmatch *)_V11)->_1) == SAME &&
3145 ((Match_RANGEmatch *)_V10)->_3 == ((Match_RANGEmatch *)_V11)->_3 && ((Match_RANGEmatch *)_V10)->_4 == ((Match_RANGEmatch *)_V11)->_4 && ((Match_RANGEmatch *)_V10)->_5 == ((Match_RANGEmatch *)_V11)->_5 && ((Match_RANGEmatch *)_V10)->_6 == ((Match_RANGEmatch *)_V11)->_6;
3147 #line 1131 "matchcom.pcc"
3148 } break;
3149 default: { goto L44; } break;
3151 } else { goto L44; }
3152 } break;
3153 case a_Match::tag_CONSmatch: {
3154 if (boxed(_V11)) {
3155 switch (_V11->tag__) {
3156 case a_Match::tag_CONSmatch: {
3157 if (
3158 #line 1123 "matchcom.pcc"
3159 ((((Match_CONSmatch *)_V10)->_4 == ((Match_CONSmatch *)_V11)->_4) && (((Match_CONSmatch *)_V10)->_5 == ((Match_CONSmatch *)_V11)->_5))
3160 #line 1123 "matchcom.pcc"
3163 #line 1124 "matchcom.pcc"
3164 if (compare_pos(((Match_CONSmatch *)_V10)->_1,((Match_CONSmatch *)_V11)->_1) != SAME) return false;
3165 for (int k = ((Match_CONSmatch *)_V10)->_5-1; k >= 0; k--) if (((Match_CONSmatch *)_V10)->_6[k] != ((Match_CONSmatch *)_V11)->_6[k]) return false;
3166 return ((Match_CONSmatch *)_V10)->_7 == ((Match_CONSmatch *)_V11)->_7;
3168 #line 1127 "matchcom.pcc"
3169 } else {
3170 goto L44; }
3171 } break;
3172 default: { goto L44; } break;
3174 } else { goto L44; }
3175 } break;
3176 case a_Match::tag_TREECOSTmatch: {
3177 if (boxed(_V11)) {
3178 switch (_V11->tag__) {
3179 case a_Match::tag_TREECOSTmatch: {
3180 #line 1115 "matchcom.pcc"
3181 return ((Match_TREECOSTmatch *)_V10)->_1 == ((Match_TREECOSTmatch *)_V11)->_1 && equal(((Match_TREECOSTmatch *)_V10)->_2,((Match_TREECOSTmatch *)_V11)->_2);
3182 #line 1115 "matchcom.pcc"
3183 } break;
3184 default: { goto L44; } break;
3186 } else { goto L44; }
3187 } break;
3188 case a_Match::tag_TREELABELmatch: {
3189 if (boxed(_V11)) {
3190 switch (_V11->tag__) {
3191 case a_Match::tag_TREELABELmatch: {
3192 #line 1117 "matchcom.pcc"
3193 return ((Match_TREELABELmatch *)_V10)->_1 == ((Match_TREELABELmatch *)_V11)->_1 && ty_equal(((Match_TREELABELmatch *)_V10)->_2,((Match_TREELABELmatch *)_V11)->_2) && ty_equal(((Match_TREELABELmatch *)_V10)->_3,((Match_TREELABELmatch *)_V11)->_3) && ((Match_TREELABELmatch *)_V10)->_4 == ((Match_TREELABELmatch *)_V11)->_4;
3194 #line 1117 "matchcom.pcc"
3195 } break;
3196 default: { goto L44; } break;
3198 } else { goto L44; }
3199 } break;
3200 default: { goto L44; } break;
3202 } else {
3203 if (_V10) {
3204 goto L44; } else {
3206 if (boxed(_V11)) { goto L44; } else {
3207 if (_V11) {
3208 goto L44; } else {
3210 #line 1108 "matchcom.pcc"
3211 return true;
3212 #line 1108 "matchcom.pcc"
3218 #line 1133 "matchcom.pcc"
3219 #line 1133 "matchcom.pcc"
3223 ///////////////////////////////////////////////////////////////////////////////
3225 // Hashing function on a literal.
3227 ///////////////////////////////////////////////////////////////////////////////
3228 unsigned int literal_hash (HashTable::Key k)
3230 #line 1142 "matchcom.pcc"
3231 #line 1150 "matchcom.pcc"
3233 Literal _V12 = Literal(k);
3234 switch (_V12->tag__) {
3235 case a_Literal::tag_INTlit: {
3236 #line 1143 "matchcom.pcc"
3237 return ((Literal_INTlit *)_V12)->INTlit;
3238 #line 1143 "matchcom.pcc"
3239 } break;
3240 case a_Literal::tag_BOOLlit: {
3241 #line 1144 "matchcom.pcc"
3242 return ((Literal_BOOLlit *)_V12)->BOOLlit;
3243 #line 1144 "matchcom.pcc"
3244 } break;
3245 case a_Literal::tag_CHARlit: {
3246 #line 1148 "matchcom.pcc"
3247 return ((Literal_CHARlit *)_V12)->CHARlit;
3248 #line 1148 "matchcom.pcc"
3249 } break;
3250 case a_Literal::tag_REALlit: {
3251 #line 1145 "matchcom.pcc"
3252 return (unsigned int)((Literal_REALlit *)_V12)->REALlit;
3253 #line 1145 "matchcom.pcc"
3254 } break;
3255 case a_Literal::tag_STRINGlit: {
3256 #line 1146 "matchcom.pcc"
3257 return hash(((Literal_STRINGlit *)_V12)->STRINGlit);
3258 #line 1146 "matchcom.pcc"
3259 } break;
3260 case a_Literal::tag_REGEXPlit: {
3261 #line 1147 "matchcom.pcc"
3262 return hash(((Literal_REGEXPlit *)_V12)->REGEXPlit);
3263 #line 1147 "matchcom.pcc"
3264 } break;
3265 case a_Literal::tag_QUARKlit: {
3266 #line 1149 "matchcom.pcc"
3267 return hash(((Literal_QUARKlit *)_V12)->QUARKlit);
3268 #line 1149 "matchcom.pcc"
3269 } break;
3270 default: {
3271 #line 1150 "matchcom.pcc"
3272 return hash(((Literal_BIGINTlit *)_V12)->BIGINTlit);
3273 #line 1150 "matchcom.pcc"
3274 } break;
3277 #line 1151 "matchcom.pcc"
3278 #line 1151 "matchcom.pcc"
3282 ///////////////////////////////////////////////////////////////////////////////
3284 // Equality function on literals.
3286 ///////////////////////////////////////////////////////////////////////////////
3287 Bool literal_equal (HashTable::Key a, HashTable::Key b)
3288 { return compare_literals((Literal)a, (Literal)b) == 0; }
3290 ///////////////////////////////////////////////////////////////////////////////
3292 // Hashing function on a matching tree.
3294 ///////////////////////////////////////////////////////////////////////////////
3295 unsigned int match_hash (HashTable::Key m)
3297 #line 1168 "matchcom.pcc"
3298 #line 1191 "matchcom.pcc"
3300 Match _V13 = Match(m);
3301 if (boxed(_V13)) {
3302 switch (_V13->tag__) {
3303 case a_Match::tag_SUCCESSmatch: {
3304 #line 1172 "matchcom.pcc"
3305 return (unsigned int)m;
3306 #line 1172 "matchcom.pcc"
3307 } break;
3308 case a_Match::tag_SUCCESSESmatch: {
3309 #line 1173 "matchcom.pcc"
3310 return 93 + hash (((Match_SUCCESSESmatch *)_V13)->_2);
3311 #line 1173 "matchcom.pcc"
3312 } break;
3313 case a_Match::tag_COSTmatch: {
3314 #line 1174 "matchcom.pcc"
3315 return 457 + hash (((Match_COSTmatch *)_V13)->_3);
3316 #line 1174 "matchcom.pcc"
3317 } break;
3318 case a_Match::tag_GUARDmatch: {
3319 #line 1177 "matchcom.pcc"
3320 return (unsigned int)((Match_GUARDmatch *)_V13)->_2 + (unsigned int)((Match_GUARDmatch *)_V13)->_3;
3321 #line 1177 "matchcom.pcc"
3322 } break;
3323 case a_Match::tag_LITERALmatch: {
3324 #line 1181 "matchcom.pcc"
3325 unsigned h = 117 + ((Match_LITERALmatch *)_V13)->_4 + (unsigned int)((Match_LITERALmatch *)_V13)->_6;
3326 for (int i = ((Match_LITERALmatch *)_V13)->_4 - 1; i >= 0; i--)
3327 h += literal_hash(((Match_LITERALmatch *)_V13)->_3[i]) + (unsigned int)((Match_LITERALmatch *)_V13)->_5[i];
3328 return h;
3330 #line 1185 "matchcom.pcc"
3331 } break;
3332 case a_Match::tag_RANGEmatch: {
3333 #line 1179 "matchcom.pcc"
3334 return 235 + ((Match_RANGEmatch *)_V13)->_3 + ((Match_RANGEmatch *)_V13)->_4 + (unsigned int)((Match_RANGEmatch *)_V13)->_5 + (unsigned int)((Match_RANGEmatch *)_V13)->_6;
3335 #line 1179 "matchcom.pcc"
3336 } break;
3337 case a_Match::tag_CONSmatch: {
3338 #line 1187 "matchcom.pcc"
3339 unsigned h = 657 + ((Match_CONSmatch *)_V13)->_5 + (unsigned int)((Match_CONSmatch *)_V13)->_7;
3340 for (int i = ((Match_CONSmatch *)_V13)->_5 - 1; i >= 0; i--)
3341 h += (unsigned int)((Match_CONSmatch *)_V13)->_6[i];
3342 return h;
3344 #line 1191 "matchcom.pcc"
3345 } break;
3346 case a_Match::tag_TREECOSTmatch: {
3347 #line 1175 "matchcom.pcc"
3348 return hash(((Match_TREECOSTmatch *)_V13)->_2) + (unsigned int)((Match_TREECOSTmatch *)_V13)->_1;
3349 #line 1175 "matchcom.pcc"
3350 } break;
3351 case a_Match::tag_TREELABELmatch: {
3352 #line 1176 "matchcom.pcc"
3353 return ty_hash(((Match_TREELABELmatch *)_V13)->_2) + ty_hash(((Match_TREELABELmatch *)_V13)->_3) + ((Match_TREELABELmatch *)_V13)->_4 + (unsigned int)((Match_TREELABELmatch *)_V13)->_1;
3354 #line 1176 "matchcom.pcc"
3355 } break;
3356 default: {
3357 #line 1171 "matchcom.pcc"
3358 return ((Match_BACKEDGEmatch *)_V13)->_1 + 1249;
3359 #line 1171 "matchcom.pcc"
3360 } break;
3362 } else {
3363 if (_V13) {
3365 #line 1170 "matchcom.pcc"
3366 return 179;
3367 #line 1170 "matchcom.pcc"
3368 } else {
3370 #line 1169 "matchcom.pcc"
3371 return 0;
3372 #line 1169 "matchcom.pcc"
3376 #line 1192 "matchcom.pcc"
3377 #line 1192 "matchcom.pcc"
3381 ///////////////////////////////////////////////////////////////////////////////
3383 // Tree to dag conversion for a matching tree.
3385 ///////////////////////////////////////////////////////////////////////////////
3386 Match make_dag (Match m, HashTable& map, int& merges)
3387 { int i;
3388 if (boxed(m)) { m->shared = 0; m->label = 0; }
3390 #line 1203 "matchcom.pcc"
3391 #line 1237 "matchcom.pcc"
3393 if (boxed(m)) {
3394 switch (m->tag__) {
3395 case a_Match::tag_GUARDmatch: {
3396 #line 1228 "matchcom.pcc"
3397 if ((((Match_GUARDmatch *)m)->_2 = make_dag(((Match_GUARDmatch *)m)->_2,map,merges)) == (((Match_GUARDmatch *)m)->_3 = make_dag(((Match_GUARDmatch *)m)->_3,map,merges)))
3398 { merges++; return ((Match_GUARDmatch *)m)->_2; }
3400 #line 1230 "matchcom.pcc"
3401 } break;
3402 case a_Match::tag_LITERALmatch: {
3403 #line 1205 "matchcom.pcc"
3404 for (i = ((Match_LITERALmatch *)m)->_4 - 1; i >= 0; i--) ((Match_LITERALmatch *)m)->_5[i] = make_dag (((Match_LITERALmatch *)m)->_5[i], map, merges);
3405 ((Match_LITERALmatch *)m)->_6 = make_dag(((Match_LITERALmatch *)m)->_6, map, merges);
3406 // Eliminate the node if every branch is the same.
3407 for (i = ((Match_LITERALmatch *)m)->_4 - 1; i >= 1; i--) if (((Match_LITERALmatch *)m)->_5[i] != ((Match_LITERALmatch *)m)->_5[i-1]) break;
3408 if (i == 0 && ((Match_LITERALmatch *)m)->_5[0] == ((Match_LITERALmatch *)m)->_6) { merges++; return ((Match_LITERALmatch *)m)->_6; }
3409 // Eliminate all branches that are the same as the default
3410 for (i = 0; i < ((Match_LITERALmatch *)m)->_4; i++)
3411 { if (((Match_LITERALmatch *)m)->_5[i] == ((Match_LITERALmatch *)m)->_6)
3412 { // shift one over
3413 for (int j = i+1; j < ((Match_LITERALmatch *)m)->_4; j++)
3414 { ((Match_LITERALmatch *)m)->_5[j-1] = ((Match_LITERALmatch *)m)->_5[j]; ((Match_LITERALmatch *)m)->_3[j-1] = ((Match_LITERALmatch *)m)->_3[j]; }
3415 ((Match_LITERALmatch *)m)->_4--;
3419 #line 1219 "matchcom.pcc"
3420 } break;
3421 case a_Match::tag_RANGEmatch: {
3422 #line 1232 "matchcom.pcc"
3423 if ((((Match_RANGEmatch *)m)->_5 = make_dag(((Match_RANGEmatch *)m)->_5,map,merges)) == (((Match_RANGEmatch *)m)->_6 = make_dag(((Match_RANGEmatch *)m)->_6,map,merges)))
3424 { merges++; return ((Match_RANGEmatch *)m)->_5; }
3426 #line 1234 "matchcom.pcc"
3427 } break;
3428 case a_Match::tag_CONSmatch: {
3429 #line 1221 "matchcom.pcc"
3430 for (i = ((Match_CONSmatch *)m)->_5 - 1; i >= 0; i--) ((Match_CONSmatch *)m)->_6[i] = make_dag (((Match_CONSmatch *)m)->_6[i], map, merges);
3431 ((Match_CONSmatch *)m)->_7 = make_dag(((Match_CONSmatch *)m)->_7, map, merges);
3432 // Eliminate the node if every branch is the same.
3433 for (i = ((Match_CONSmatch *)m)->_5 - 1; i >= 1; i--) if (((Match_CONSmatch *)m)->_6[i] != ((Match_CONSmatch *)m)->_6[i-1]) break;
3434 if (i == 0 && ((Match_CONSmatch *)m)->_6[0] == ((Match_CONSmatch *)m)->_7) { merges++; return ((Match_CONSmatch *)m)->_7; }
3436 #line 1226 "matchcom.pcc"
3437 } break;
3438 case a_Match::tag_TREECOSTmatch: {
3439 #line 1235 "matchcom.pcc"
3440 ((Match_TREECOSTmatch *)m)->_1 = make_dag(((Match_TREECOSTmatch *)m)->_1,map,merges);
3441 #line 1235 "matchcom.pcc"
3442 } break;
3443 case a_Match::tag_TREELABELmatch: {
3444 #line 1236 "matchcom.pcc"
3445 ((Match_TREELABELmatch *)m)->_1 = make_dag(((Match_TREELABELmatch *)m)->_1,map,merges);
3446 #line 1236 "matchcom.pcc"
3447 } break;
3448 default: {
3449 L45:;
3450 #line 1237 "matchcom.pcc"
3451 /* skip */
3452 #line 1237 "matchcom.pcc"
3453 } break;
3455 } else { goto L45; }
3457 #line 1238 "matchcom.pcc"
3458 #line 1238 "matchcom.pcc"
3461 HashTable::Entry * found = map.lookup(m);
3462 if (found) {
3463 merges++;
3464 return (Match)found->v;
3465 } else {
3466 map.insert(m,m);
3467 return m;
3471 ///////////////////////////////////////////////////////////////////////////////
3473 // Mark all sharing
3475 ///////////////////////////////////////////////////////////////////////////////
3476 void mark(Match m)
3477 { if (boxed(m)) m->shared++;
3479 #line 1257 "matchcom.pcc"
3480 #line 1284 "matchcom.pcc"
3482 if (boxed(m)) {
3483 switch (m->tag__) {
3484 case a_Match::tag_SUCCESSmatch: {
3485 #line 1258 "matchcom.pcc"
3486 ((Match_SUCCESSmatch *)m)->_2->used = true;
3487 #line 1258 "matchcom.pcc"
3488 } break;
3489 case a_Match::tag_GUARDmatch: {
3490 #line 1261 "matchcom.pcc"
3491 mark(((Match_GUARDmatch *)m)->_2); mark(((Match_GUARDmatch *)m)->_3);
3492 #line 1261 "matchcom.pcc"
3493 } break;
3494 case a_Match::tag_LITERALmatch: {
3495 #line 1262 "matchcom.pcc"
3496 for (int i = ((Match_LITERALmatch *)m)->_4-1; i >= 0; i--) mark(((Match_LITERALmatch *)m)->_5[i]);
3497 mark(((Match_LITERALmatch *)m)->_6);
3499 #line 1264 "matchcom.pcc"
3500 } break;
3501 case a_Match::tag_RANGEmatch: {
3502 #line 1265 "matchcom.pcc"
3503 mark(((Match_RANGEmatch *)m)->_5); mark(((Match_RANGEmatch *)m)->_6);
3504 #line 1265 "matchcom.pcc"
3505 } break;
3506 case a_Match::tag_CONSmatch: {
3507 if (((Match_CONSmatch *)m)->_4) {
3508 switch (((Match_CONSmatch *)m)->_4->tag__) {
3509 case a_Ty::tag_TYCONty: {
3510 if (boxed(((Ty_TYCONty *)((Match_CONSmatch *)m)->_4)->_1)) {
3511 switch (((Ty_TYCONty *)((Match_CONSmatch *)m)->_4)->_1->tag__) {
3512 case a_TyCon::tag_DATATYPEtycon: {
3513 #line 1269 "matchcom.pcc"
3514 for (int i = ((Match_CONSmatch *)m)->_5-1; i >= 0; i--) mark(((Match_CONSmatch *)m)->_6[i]);
3515 // if (unit > 0)
3516 // { int i;
3517 // for (i = unit - 2; i >= 0; i--) if (a[i] != a[i+1]) break;
3518 // if (i < 0) mark(a[0]);
3519 // else for (i = unit - 1; i >= 0; i--) mark(a[i]);
3520 // }
3521 // if (arg > 0)
3522 // { int i;
3523 // for (i = n - 2; i >= unit; i--) if (a[i] != a[i+1]) break;
3524 // if (i < unit) mark(a[unit]);
3525 // else for (i = n - 1; i >= unit; i--) mark(a[i]);
3526 // }
3527 if (((TyCon_DATATYPEtycon *)((Ty_TYCONty *)((Match_CONSmatch *)m)->_4)->_1)->qualifiers & QUALextensible) mark(((Match_CONSmatch *)m)->_7);
3529 #line 1283 "matchcom.pcc"
3530 } break;
3531 default: {
3532 L46:;
3533 #line 1284 "matchcom.pcc"
3534 bug ("mark()");
3535 #line 1284 "matchcom.pcc"
3536 } break;
3538 } else { goto L46; }
3539 } break;
3540 default: { goto L46; } break;
3542 } else { goto L46; }
3543 } break;
3544 case a_Match::tag_TREECOSTmatch: {
3545 #line 1266 "matchcom.pcc"
3546 mark(((Match_TREECOSTmatch *)m)->_1);
3547 #line 1266 "matchcom.pcc"
3548 } break;
3549 case a_Match::tag_TREELABELmatch: {
3550 #line 1267 "matchcom.pcc"
3551 mark(((Match_TREELABELmatch *)m)->_1);
3552 #line 1267 "matchcom.pcc"
3553 } break;
3554 case a_Match::tag_BACKEDGEmatch: { goto L46; } break;
3555 default: {
3556 L47:;
3557 #line 1260 "matchcom.pcc"
3558 /* skip */
3559 #line 1260 "matchcom.pcc"
3560 } break;
3562 } else {
3563 if (m) {
3564 goto L46; } else {
3565 goto L47; }
3568 #line 1285 "matchcom.pcc"
3569 #line 1285 "matchcom.pcc"
3573 ///////////////////////////////////////////////////////////////////////////////
3575 // Top level tree to dag conversion.
3577 ///////////////////////////////////////////////////////////////////////////////
3578 Match MatchCompiler::make_dag (Match m, MatchOptions options, MatchRules rules)
3579 { HashTable map(match_hash, match_equal, 257);
3580 m = ::make_dag(m,map,merges);
3581 if (options & MATCHwithtreecost)
3582 m = translate_treecost(m,rules);
3583 mark(m);
3584 return m;
3587 ///////////////////////////////////////////////////////////////////////////////
3589 // Check to see if a matching tree is refutable (i.e. can fail.)
3591 ///////////////////////////////////////////////////////////////////////////////
3592 Bool refutable (Match m)
3594 #line 1308 "matchcom.pcc"
3595 #line 1327 "matchcom.pcc"
3597 for (;;) {
3598 if (boxed(m)) {
3599 switch (m->tag__) {
3600 case a_Match::tag_GUARDmatch: {
3601 #line 1311 "matchcom.pcc"
3602 return refutable(((Match_GUARDmatch *)m)->_2) || refutable(((Match_GUARDmatch *)m)->_3);
3603 #line 1311 "matchcom.pcc"
3604 } break;
3605 case a_Match::tag_LITERALmatch: {
3606 #line 1314 "matchcom.pcc"
3607 for (int i = ((Match_LITERALmatch *)m)->_4 - 1; i >= 0; i--) if (refutable(((Match_LITERALmatch *)m)->_5[i])) return true;
3609 #line 1315 "matchcom.pcc"
3610 #line 1317 "matchcom.pcc"
3612 Literal _V14 = ((Match_LITERALmatch *)m)->_3[0];
3613 switch (_V14->tag__) {
3614 case a_Literal::tag_BOOLlit: {
3615 if (
3616 #line 1316 "matchcom.pcc"
3617 (((Match_LITERALmatch *)m)->_4 >= 2)
3618 #line 1316 "matchcom.pcc"
3621 #line 1316 "matchcom.pcc"
3622 return false;
3623 #line 1316 "matchcom.pcc"
3624 } else {
3626 L49:;
3627 #line 1317 "matchcom.pcc"
3628 m = ((Match_LITERALmatch *)m)->_6;
3629 #line 1317 "matchcom.pcc"
3631 } break;
3632 default: { goto L49; } break;
3635 #line 1318 "matchcom.pcc"
3636 #line 1318 "matchcom.pcc"
3639 #line 1319 "matchcom.pcc"
3640 } break;
3641 case a_Match::tag_RANGEmatch: {
3642 #line 1312 "matchcom.pcc"
3643 return refutable(((Match_RANGEmatch *)m)->_5) || refutable(((Match_RANGEmatch *)m)->_6);
3644 #line 1312 "matchcom.pcc"
3645 } break;
3646 case a_Match::tag_CONSmatch: {
3647 if (((Match_CONSmatch *)m)->_4) {
3648 switch (((Match_CONSmatch *)m)->_4->tag__) {
3649 case a_Ty::tag_TYCONty: {
3650 if (boxed(((Ty_TYCONty *)((Match_CONSmatch *)m)->_4)->_1)) {
3651 switch (((Ty_TYCONty *)((Match_CONSmatch *)m)->_4)->_1->tag__) {
3652 case a_TyCon::tag_DATATYPEtycon: {
3653 #line 1321 "matchcom.pcc"
3654 for (int i = ((Match_CONSmatch *)m)->_5 - 1; i >= 0; i--) if (refutable(((Match_CONSmatch *)m)->_6[i])) return true;
3655 if (! (((TyCon_DATATYPEtycon *)((Ty_TYCONty *)((Match_CONSmatch *)m)->_4)->_1)->qualifiers & QUALextensible)) return false;
3656 m = ((Match_CONSmatch *)m)->_7;
3658 #line 1324 "matchcom.pcc"
3659 } break;
3660 default: {
3661 L50:;
3662 #line 1327 "matchcom.pcc"
3663 bug ("refutable()");
3664 #line 1327 "matchcom.pcc"
3665 } break;
3667 } else { goto L50; }
3668 } break;
3669 default: { goto L50; } break;
3671 } else { goto L50; }
3672 } break;
3673 case a_Match::tag_TREECOSTmatch: {
3674 #line 1325 "matchcom.pcc"
3675 m = ((Match_TREECOSTmatch *)m)->_1;
3676 #line 1325 "matchcom.pcc"
3677 } break;
3678 case a_Match::tag_TREELABELmatch: {
3679 #line 1326 "matchcom.pcc"
3680 m = ((Match_TREELABELmatch *)m)->_1;
3681 #line 1326 "matchcom.pcc"
3682 } break;
3683 case a_Match::tag_BACKEDGEmatch: { goto L50; } break;
3684 default: {
3685 #line 1310 "matchcom.pcc"
3686 return false;
3687 #line 1310 "matchcom.pcc"
3688 } break;
3690 } else {
3691 if (m) {
3692 goto L50; } else {
3694 #line 1309 "matchcom.pcc"
3695 return true;
3696 #line 1309 "matchcom.pcc"
3701 #line 1328 "matchcom.pcc"
3702 #line 1328 "matchcom.pcc"
3706 ///////////////////////////////////////////////////////////////////////////////
3708 // Compute the set of rules that can possibly match as a bitset.
3710 ///////////////////////////////////////////////////////////////////////////////
3711 void matchables (Match m, BitSet& set)
3713 #line 1337 "matchcom.pcc"
3714 #line 1355 "matchcom.pcc"
3716 for (;;) {
3717 if (boxed(m)) {
3718 switch (m->tag__) {
3719 case a_Match::tag_SUCCESSmatch: {
3720 #line 1341 "matchcom.pcc"
3721 set.add(((Match_SUCCESSmatch *)m)->_1); return;
3722 #line 1341 "matchcom.pcc"
3723 } break;
3724 case a_Match::tag_SUCCESSESmatch: {
3725 #line 1339 "matchcom.pcc"
3726 set.Union(*((Match_SUCCESSESmatch *)m)->_2); return;
3727 #line 1339 "matchcom.pcc"
3728 } break;
3729 case a_Match::tag_COSTmatch: {
3730 #line 1340 "matchcom.pcc"
3731 set.Union(*((Match_COSTmatch *)m)->_3); return;
3732 #line 1340 "matchcom.pcc"
3733 } break;
3734 case a_Match::tag_GUARDmatch: {
3735 #line 1342 "matchcom.pcc"
3736 matchables(((Match_GUARDmatch *)m)->_2,set); m = ((Match_GUARDmatch *)m)->_3;
3737 #line 1342 "matchcom.pcc"
3738 } break;
3739 case a_Match::tag_LITERALmatch: {
3740 #line 1345 "matchcom.pcc"
3741 for (int i = ((Match_LITERALmatch *)m)->_4 - 1; i >= 0; i--) matchables(((Match_LITERALmatch *)m)->_5[i],set);
3742 m = ((Match_LITERALmatch *)m)->_6;
3744 #line 1347 "matchcom.pcc"
3745 } break;
3746 case a_Match::tag_RANGEmatch: {
3747 #line 1343 "matchcom.pcc"
3748 matchables(((Match_RANGEmatch *)m)->_5,set); m = ((Match_RANGEmatch *)m)->_6;
3749 #line 1343 "matchcom.pcc"
3750 } break;
3751 case a_Match::tag_CONSmatch: {
3752 if (((Match_CONSmatch *)m)->_4) {
3753 switch (((Match_CONSmatch *)m)->_4->tag__) {
3754 case a_Ty::tag_TYCONty: {
3755 if (boxed(((Ty_TYCONty *)((Match_CONSmatch *)m)->_4)->_1)) {
3756 switch (((Ty_TYCONty *)((Match_CONSmatch *)m)->_4)->_1->tag__) {
3757 case a_TyCon::tag_DATATYPEtycon: {
3758 #line 1349 "matchcom.pcc"
3759 for (int i = ((Match_CONSmatch *)m)->_5 - 1; i >= 0; i--) matchables(((Match_CONSmatch *)m)->_6[i],set);
3760 if (! (((TyCon_DATATYPEtycon *)((Ty_TYCONty *)((Match_CONSmatch *)m)->_4)->_1)->qualifiers & QUALextensible)) return;
3761 m = ((Match_CONSmatch *)m)->_7;
3763 #line 1352 "matchcom.pcc"
3764 } break;
3765 default: {
3766 L52:;
3767 #line 1355 "matchcom.pcc"
3768 bug("matchables()");
3769 #line 1355 "matchcom.pcc"
3770 } break;
3772 } else { goto L52; }
3773 } break;
3774 default: { goto L52; } break;
3776 } else { goto L52; }
3777 } break;
3778 case a_Match::tag_TREECOSTmatch: {
3779 #line 1353 "matchcom.pcc"
3780 set.Union(*((Match_TREECOSTmatch *)m)->_2); m = ((Match_TREECOSTmatch *)m)->_1;
3781 #line 1353 "matchcom.pcc"
3782 } break;
3783 case a_Match::tag_TREELABELmatch: {
3784 #line 1354 "matchcom.pcc"
3785 m = ((Match_TREELABELmatch *)m)->_1;
3786 #line 1354 "matchcom.pcc"
3787 } break;
3788 default: { goto L52; } break;
3790 } else {
3791 if (m) {
3792 goto L52; } else {
3794 #line 1338 "matchcom.pcc"
3795 return;
3796 #line 1338 "matchcom.pcc"
3801 #line 1356 "matchcom.pcc"
3802 #line 1356 "matchcom.pcc"
3806 ///////////////////////////////////////////////////////////////////////////////
3808 // Compute the set of rules that can always match as a bitset.
3810 ///////////////////////////////////////////////////////////////////////////////
3811 void always_matchables (Match m, BitSet& set)
3813 #line 1365 "matchcom.pcc"
3814 #line 1380 "matchcom.pcc"
3816 for (;;) {
3817 if (boxed(m)) {
3818 switch (m->tag__) {
3819 case a_Match::tag_SUCCESSESmatch: {
3820 #line 1366 "matchcom.pcc"
3821 set.Intersect(*((Match_SUCCESSESmatch *)m)->_2); return;
3822 #line 1366 "matchcom.pcc"
3823 } break;
3824 case a_Match::tag_COSTmatch: {
3825 #line 1367 "matchcom.pcc"
3826 set.Intersect(*((Match_COSTmatch *)m)->_3); return;
3827 #line 1367 "matchcom.pcc"
3828 } break;
3829 case a_Match::tag_GUARDmatch: {
3830 #line 1368 "matchcom.pcc"
3831 always_matchables(((Match_GUARDmatch *)m)->_2,set); m = ((Match_GUARDmatch *)m)->_3;
3832 #line 1368 "matchcom.pcc"
3833 } break;
3834 case a_Match::tag_LITERALmatch: {
3835 #line 1371 "matchcom.pcc"
3836 for (int i = ((Match_LITERALmatch *)m)->_4 - 1; i >= 0; i--) always_matchables(((Match_LITERALmatch *)m)->_5[i],set);
3837 m = ((Match_LITERALmatch *)m)->_6;
3839 #line 1373 "matchcom.pcc"
3840 } break;
3841 case a_Match::tag_RANGEmatch: {
3842 #line 1369 "matchcom.pcc"
3843 always_matchables(((Match_RANGEmatch *)m)->_5,set); m = ((Match_RANGEmatch *)m)->_6;
3844 #line 1369 "matchcom.pcc"
3845 } break;
3846 case a_Match::tag_CONSmatch: {
3847 if (((Match_CONSmatch *)m)->_4) {
3848 switch (((Match_CONSmatch *)m)->_4->tag__) {
3849 case a_Ty::tag_TYCONty: {
3850 if (boxed(((Ty_TYCONty *)((Match_CONSmatch *)m)->_4)->_1)) {
3851 switch (((Ty_TYCONty *)((Match_CONSmatch *)m)->_4)->_1->tag__) {
3852 case a_TyCon::tag_DATATYPEtycon: {
3853 #line 1375 "matchcom.pcc"
3854 for (int i = ((Match_CONSmatch *)m)->_5 - 1; i >= 0; i--) always_matchables(((Match_CONSmatch *)m)->_6[i],set);
3855 if (! (((TyCon_DATATYPEtycon *)((Ty_TYCONty *)((Match_CONSmatch *)m)->_4)->_1)->qualifiers & QUALextensible)) return;
3856 m = ((Match_CONSmatch *)m)->_7;
3858 #line 1378 "matchcom.pcc"
3859 } break;
3860 default: { goto L53; } break;
3862 } else { goto L53; }
3863 } break;
3864 default: { goto L53; } break;
3866 } else { goto L53; }
3867 } break;
3868 case a_Match::tag_TREECOSTmatch: {
3869 #line 1379 "matchcom.pcc"
3870 set.Intersect(*((Match_TREECOSTmatch *)m)->_2); m = ((Match_TREECOSTmatch *)m)->_1;
3871 #line 1379 "matchcom.pcc"
3872 } break;
3873 case a_Match::tag_TREELABELmatch: {
3874 #line 1380 "matchcom.pcc"
3875 m = ((Match_TREELABELmatch *)m)->_1;
3876 #line 1380 "matchcom.pcc"
3877 } break;
3878 default: { goto L53; } break;
3880 } else { goto L53; }
3882 L53:;
3884 #line 1381 "matchcom.pcc"
3885 #line 1381 "matchcom.pcc"
3889 ///////////////////////////////////////////////////////////////////////////////
3891 // Top level routine to call the above
3893 ///////////////////////////////////////////////////////////////////////////////
3894 const BitSet& always_matchables(Match m, int n)
3895 { BitSet * set = new (mem_pool, n) BitSet;
3896 set->complement();
3897 always_matchables(m, *set);
3898 return *set;
3900 #line 1395 "matchcom.pcc"
3902 ------------------------------- Statistics -------------------------------
3903 Merge matching rules = yes
3904 Number of DFA nodes merged = 3366
3905 Number of ifs generated = 151
3906 Number of switches generated = 114
3907 Number of labels = 44
3908 Number of gotos = 210
3909 Adaptive matching = enabled
3910 Fast string matching = disabled
3911 Inline downcasts = enabled
3912 --------------------------------------------------------------------------