initial
[prop.git] / prop-src / rwgen4.pcc
blobde7d7cca4ecc9a556141410beddf22eb83d276d3
1 ///////////////////////////////////////////////////////////////////////////////
2 //
3 //  This file implements the tree rewriting/tree parsing compiler.
4 //  This is used to implement the rewrite class/rewrite constructs of Prop.
5 //
6 ///////////////////////////////////////////////////////////////////////////////
7 #include <iostream.h>
8 #include <strstream.h>
9 #include "funmap.ph"
10 #include "ir.ph"
11 #include "ast.ph"
12 #include "matchcom.ph"
13 #include "type.h"
14 #include "hashtab.h"
15 #include "list.h"
16 #include "rwgen.h"
17 #include "trs.h"
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",
29          F.class_name, ty);
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); 
32    }
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)
78    pr("%n%/"
79       "%n//"
80       "%n// This macro can be redefined by the user for debugging" 
81       "%n//"
82       "%n%/"
83       "%n#ifndef DEBUG_%S"
84       "%n#define DEBUG_%S(repl,redex,file,line,rule) repl"
85       "%n#else"
86       "%nstatic const char * %S_file_name = \"%s\";"
87       "%n#endif\n\n",
88       name, name, name, file 
89       );
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; }
106    end match;
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)
117 {   Bool optimized = 
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()
122       );
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)
143 {  if (Fmap == 0)
144    {  error("%Lcutrewrite is not used within a rewrite class: cutrewrite %e\n",
145             exp);
146       return;
147    }
148    if (Fmap->is_applicative)
149    {  if (exp == NOexp) 
150          pr("%^{ s__ = 0; return redex; }"); 
151       else
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());
155    } else 
156    {  if (exp == NOexp) 
157          pr("%^{ s__ = 0; return; }"); 
158       else
159          pr("%^{ s__ = 0; redex = DEBUG_%S(%e,redex);"
160             " return; }", 
161             Fmap->class_name, exp, Fmap->class_name,
162             current_rule_line(), current_rule_text());
163    }