Inferno  0.2
inferno_patterns.hpp
Go to the documentation of this file.
00001 #ifndef INFERNO_PATTERNS_HPP
00002 #define INFERNO_PATTERNS_HPP
00003 
00004 #include "sr/search_replace.hpp"
00005 #include "tree/cpptree.hpp" // TODO this dep means we must move this into steps/ or at least parts
00006 #include "helpers/transformation.hpp"
00007 
00008 
00009 // Make an identifer based on an existing one. New identfier is named using
00010 // sprintf( format, source->name )
00011 // You must key the source identifier to somehting in the search pattern (so it
00012 // will get substitued to the real Specific identifier found in the tree) and
00013 // you may couple the SoftMakeIdentifier in the replace pattern if you need
00014 // to specify it in more than one place. Note that SoftMakeIdentifier is stateless
00015 // and cannot therefore keep track of uniqueness - you'll get a new one each time
00016 // and must rely on a replace coupling to get multiple reference to the same
00017 // new identifier. Rule is: ONE of these per new identifier.
00018 
00019 // TODO do this via a transformation as with TransformOf/TransformOf
00020 #define BYPASS_WHEN_IDENTICAL 1
00021 struct BuildIdentifierBase : ::SoftReplacePattern
00022 {
00023     BuildIdentifierBase( string s, int f=0 ) : format(s), flags(f) {}
00024     Sequence<CPPTree::Identifier> sources;
00025     string GetNewName( const CompareReplace *sr );
00026     string format;
00027     int flags;
00028 };
00029 
00030 struct BuildInstanceIdentifier : Special<CPPTree::InstanceIdentifier>,                             
00031                                  BuildIdentifierBase
00032 {
00033     SPECIAL_NODE_FUNCTIONS
00034     BuildInstanceIdentifier( string s, int f=0 ) : BuildIdentifierBase(s,f) {}
00035     BuildInstanceIdentifier() : BuildIdentifierBase("unnamed") {}
00036 private:
00037     virtual TreePtr<Node> DuplicateSubtree( const CompareReplace *sr )
00038     {
00039     string newname = GetNewName( sr );
00040     return TreePtr<CPPTree::SpecificInstanceIdentifier>( new CPPTree::SpecificInstanceIdentifier( newname ) );
00041     }                                                   
00042 };
00043 
00044 struct BuildTypeIdentifier : Special<CPPTree::TypeIdentifier>,                             
00045                              BuildIdentifierBase
00046 {
00047     SPECIAL_NODE_FUNCTIONS
00048     BuildTypeIdentifier( string s="Unnamed", int f=0 ) : BuildIdentifierBase(s,f) {}
00049 private:
00050     virtual TreePtr<Node> DuplicateSubtree( const CompareReplace *sr )
00051     {
00052     string newname = GetNewName( sr );
00053     return TreePtr<CPPTree::SpecificTypeIdentifier>( new CPPTree::SpecificTypeIdentifier( newname ) );
00054     }                                               
00055 };
00056 
00057 struct BuildLabelIdentifier : Special<CPPTree::LabelIdentifier>,                             
00058                               BuildIdentifierBase
00059 {
00060     SPECIAL_NODE_FUNCTIONS
00061     BuildLabelIdentifier() : BuildIdentifierBase("UNNAMED") {}
00062     BuildLabelIdentifier( string s, int f=0 ) : BuildIdentifierBase(s,f) {}
00063 private:
00064     virtual TreePtr<Node> DuplicateSubtree( const CompareReplace *sr )
00065     {
00066     string newname = GetNewName( sr );
00067     return TreePtr<CPPTree::SpecificLabelIdentifier>( new CPPTree::SpecificLabelIdentifier( newname ) );
00068     }                                               
00069 };
00070 
00071 
00072 
00073 // These can be used in search pattern to match a SpecificIdentifier by name.
00074 // (cannot do this using a SpecificIdentifier in the search pattern because
00075 // the address of the node would be compared, not the name string). TODO document
00076 struct IdentifierByNameBase : SoftSearchPattern
00077 {
00078     IdentifierByNameBase( string n ) : name(n) {}
00079     bool IsMatch( const CompareReplace *sr, const TreePtrInterface &x );
00080     string name;
00081 };
00082 
00083 struct InstanceIdentifierByName : Special<CPPTree::InstanceIdentifier>,                             
00084                                  IdentifierByNameBase
00085 {
00086     SPECIAL_NODE_FUNCTIONS
00087 
00088     InstanceIdentifierByName() : IdentifierByNameBase(string()) {}    
00089     InstanceIdentifierByName( string n ) : IdentifierByNameBase(n) {}
00090 private:
00091     virtual bool DecidedCompare( const CompareReplace *sr,
00092                                 const TreePtrInterface &x,
00093                                 bool can_key,
00094                                 Conjecture &conj )
00095     {
00096         return IsMatch( sr, x );
00097     }                                
00098 };
00099 
00100 struct TypeIdentifierByName : Special<CPPTree::TypeIdentifier>,                             
00101                              IdentifierByNameBase
00102 {
00103     SPECIAL_NODE_FUNCTIONS
00104 
00105     TypeIdentifierByName() : IdentifierByNameBase(string()) {}    
00106     TypeIdentifierByName( string n ) : IdentifierByNameBase(n) {}
00107 private:
00108     virtual bool DecidedCompare( const CompareReplace *sr,
00109                                 const TreePtrInterface &x,
00110                                 bool can_key,
00111                                 Conjecture &conj )
00112     {
00113         return IsMatch( sr, x );
00114     }                                
00115 };
00116 
00117 struct LabelIdentifierByName : Special<CPPTree::LabelIdentifier>,                             
00118                               IdentifierByNameBase
00119 {
00120     SPECIAL_NODE_FUNCTIONS
00121 
00122     LabelIdentifierByName() : IdentifierByNameBase(string()) {}    
00123     LabelIdentifierByName( string n ) : IdentifierByNameBase(n) {}
00124 private:
00125     virtual bool DecidedCompare( const CompareReplace *sr,
00126                                 const TreePtrInterface &x,
00127                                 bool can_key,
00128                                 Conjecture &conj )
00129     {
00130         return IsMatch( sr, x );
00131     }                                
00132 };
00133 
00134 // Base class for special nodes that match nested nodes
00135 struct NestedBase : SoftSearchPatternSpecialKey,
00136                     TerminusBase
00137 {
00138     virtual TreePtr<Node> Advance( TreePtr<Node> n, string *depth ) = 0;
00139     virtual shared_ptr<Key> DecidedCompare( const CompareReplace *sr,
00140                                             const TreePtrInterface &x,
00141                                             bool can_key,
00142                                             Conjecture &conj );
00143     TreePtr<CPPTree::String> depth;
00144 };
00145 
00146 // Recurse through a number of nested Array nodes, but only by going through
00147 // the "element" member, not the "size" member. So this will get you from the type
00148 // of an instance to the type of the eventual element in a nested array decl.
00149 struct NestedArray : NestedBase, Special<CPPTree::Type>
00150 {
00151     SPECIAL_NODE_FUNCTIONS
00152     virtual TreePtr<Node> Advance( TreePtr<Node> n, string *depth );
00153 };
00154 
00155 // Recurse through a number of Subscript nodes, but only going through
00156 // the base, not the index. Thus we seek the instance that contains the 
00157 // data we strarted with. Also go through member field of Lookup nodes.
00158 struct NestedSubscriptLookup : NestedBase, Special<CPPTree::Expression>
00159 {
00160     SPECIAL_NODE_FUNCTIONS
00161     virtual TreePtr<Node> Advance( TreePtr<Node> n, string *depth );
00162 };
00163 
00164 
00165 #endif