1 ///////////////////////////////////////////////////////////////////////////////
3 // This file implements the tree rewriting/tree parsing compiler.
4 // This is used to implement the rewrite class/rewrite constructs of Prop.
6 ///////////////////////////////////////////////////////////////////////////////
12 #include "matchcom.ph"
19 ///////////////////////////////////////////////////////////////////////////////
21 // Method to generate a set of pattern matching rules for a labeler
23 ///////////////////////////////////////////////////////////////////////////////
24 void RewritingCompiler::gen_auxiliary_rules
25 (FunctorMap& F, Ty ty, MatchRuleInfo::RewritingMode mode)
26 { if (F.rule_maps[mode]->contains(ty))
27 { MatchRules rules = rev(MatchRules((*F.rule_maps[mode])[ty]));
28 debug_msg("%Lgenerating auxiliary rules for rewrite class %s type %T:\n",
30 for_each(MatchRule,r,rules) debug_msg("%!\t%r\n",r->loc(),r);
31 gen_match_stmt(#[MATCHexp(IDexp(redex_name(ty)),0)],rules,MATCHnocheck);
35 ///////////////////////////////////////////////////////////////////////////////
37 // Method to generate the before rules of a labeler
39 ///////////////////////////////////////////////////////////////////////////////
40 void RewritingCompiler::gen_before_rules(FunctorMap& F, Ty ty)
41 { gen_auxiliary_rules(F,ty,MatchRuleInfo::BEFORE);
44 ///////////////////////////////////////////////////////////////////////////////
46 // Method to generate the preorder rules of a labeler
48 ///////////////////////////////////////////////////////////////////////////////
49 void RewritingCompiler::gen_preorder_rules(FunctorMap& F, Ty ty)
50 { gen_auxiliary_rules(F,ty,MatchRuleInfo::PREORDER);
53 ///////////////////////////////////////////////////////////////////////////////
55 // Method to generate the postorder rules of a labeler
57 ///////////////////////////////////////////////////////////////////////////////
58 void RewritingCompiler::gen_postorder_rules(FunctorMap& F, Ty ty)
59 { gen_auxiliary_rules(F,ty,MatchRuleInfo::POSTORDER);
62 ///////////////////////////////////////////////////////////////////////////////
64 // Method to generate the topdown rules of a labeler
66 ///////////////////////////////////////////////////////////////////////////////
67 void RewritingCompiler::gen_topdown_rules(FunctorMap& F, Ty ty)
68 { gen_auxiliary_rules(F,ty,MatchRuleInfo::TOPDOWN);
71 ///////////////////////////////////////////////////////////////////////////////
73 // Method to generate a tracing macro
75 ///////////////////////////////////////////////////////////////////////////////
76 void RewritingCompiler::gen_trace_macro(Id name, FunctorMap& F)
80 "%n// This macro can be redefined by the user for debugging"
84 "%n#define DEBUG_%S(repl,redex,file,line,rule) repl"
86 "%nstatic const char * %S_file_name = \"%s\";"
88 name, name, name, file
92 ///////////////////////////////////////////////////////////////////////////////
94 // Method to find out whether the replacement term is simple.
95 // A replacement term is simple if it is a projection/selection from
96 // the redex, or the redex itself.
98 ///////////////////////////////////////////////////////////////////////////////
99 Bool is_simple_replacement(Exp exp)
100 { match while (exp) of
101 IDexp "redex": { return true; }
102 | DOTexp(SELECTORexp(e,_,_),x): { exp = e; }
103 | SELECTORexp(e,_,_): { exp = e; }
104 | MARKEDexp(_,e): { exp = e; }
105 | _: { return false; }
109 ///////////////////////////////////////////////////////////////////////////////
111 // Method to generate a replacement statement. We'll optimize all
112 // bottomup and after rewriting rules.
114 ///////////////////////////////////////////////////////////////////////////////
115 void RewritingCompiler::gen_replacement
116 (Exp exp, MatchRuleInfo::RewritingMode mode)
118 trs && trs->gen_replacement(*this,current_rule->rule_number,exp);
119 pr("%^{ redex = DEBUG_%S(%e,redex,%S_file_name,%i,%s);",
120 Fmap->class_name, (optimized ? IDexp("repl__") : exp),
121 Fmap->class_name, current_rule_line(), current_rule_text()
123 pr ("%^ r__ = 1; goto replacement__; }");
126 ///////////////////////////////////////////////////////////////////////////////
128 // Method to generate a failrewrite statement.
130 ///////////////////////////////////////////////////////////////////////////////
131 void RewritingCompiler::gen_failrewrite (MatchRuleInfo::RewritingMode)
133 pr("%^{ ++o__; goto accept__; }");
136 ///////////////////////////////////////////////////////////////////////////////
138 // Method to generate a cut/replacement statement
140 ///////////////////////////////////////////////////////////////////////////////
141 void RewritingCompiler::gen_cutreplacement
142 (Exp exp, MatchRuleInfo::RewritingMode mode)
144 { error("%Lcutrewrite is not used within a rewrite class: cutrewrite %e\n",
148 if (Fmap->is_applicative)
150 pr("%^{ s__ = 0; return redex; }");
152 pr("%^{ s__ = 0; return DEBUG_%S(%e,redex,%S_file_name,%i,%s); }",
153 Fmap->class_name, exp, Fmap->class_name,
154 current_rule_line(), current_rule_text());
157 pr("%^{ s__ = 0; return; }");
159 pr("%^{ s__ = 0; redex = DEBUG_%S(%e,redex);"
161 Fmap->class_name, exp, Fmap->class_name,
162 current_rule_line(), current_rule_text());