Inferno
0.2
|
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