Inferno
0.2
|
00001 #include "inferno_patterns.hpp" 00002 #include "tree/cpptree.hpp" 00003 00004 using namespace CPPTree; 00005 00006 string BuildIdentifierBase::GetNewName( const CompareReplace *sr ) 00007 { 00008 //INDENT; 00009 TRACE("Begin SoftMakeIdentifier recurse for \"")(format)("\"\n"); 00010 vector<string> vs; 00011 bool all_same = true; 00012 FOREACH( TreePtr<Node> source, sources ) 00013 { 00014 ASSERT( source ); 00015 // We have a child identifier - let replace algorithm run in the expectation it will 00016 // get subsitituted with a SpecificIdentifier from the original program tree 00017 TreePtr<Node> n = sr->BuildReplace( TreePtr<Node>(source) ); 00018 TRACE("End SoftMakeIdentifier recurse\n"); 00019 ASSERT( n ); 00020 TreePtr<SpecificIdentifier> si = dynamic_pointer_cast<SpecificIdentifier>( n ); 00021 ASSERT( si )("BuildIdentifier: ")(*n)(" should be a kind of SpecificIdentifier (format is %s)", format.c_str()); 00022 string s = si->GetName(); 00023 if( !vs.empty() ) 00024 all_same = all_same && (s == vs.back()); 00025 vs.push_back( s ); 00026 } 00027 00028 // Optional functionality: when every identifier has the same name, just return that 00029 // name. Handy for "merging" operations. 00030 if( (flags & BYPASS_WHEN_IDENTICAL) && all_same ) 00031 return vs[0]; 00032 00033 // Use sprintf to build a new identifier based on the found one. Obviously %s 00034 // becomes the old identifier's name. 00035 switch( vs.size() ) 00036 { 00037 case 0: 00038 return SSPrintf( format.c_str() ); 00039 case 1: 00040 return SSPrintf( format.c_str(), vs[0].c_str() ); 00041 case 2: 00042 return SSPrintf( format.c_str(), vs[0].c_str(), vs[1].c_str() ); 00043 default: 00044 ASSERTFAIL("Please add more cases to GetNewName()"); 00045 } 00046 } 00047 00048 bool IdentifierByNameBase::IsMatch( const CompareReplace *sr, const TreePtrInterface &x ) 00049 { 00050 string newname = name; 00051 TreePtr<Node> nx = x; // TODO dynamic_pointer_cast support for TreePtrInterface 00052 if( TreePtr<CPPTree::SpecificIdentifier> si = dynamic_pointer_cast<CPPTree::SpecificIdentifier>(nx) ) 00053 { 00054 TRACE("IsMatch comparing ")(si->GetName())(" with ")(newname); 00055 if( si->GetName() == newname ) 00056 { 00057 TRACE(" : same\n"); 00058 return true; 00059 } 00060 TRACE(" : different\n"); 00061 } 00062 return false; 00063 } 00064 00065 00066 shared_ptr<Key> NestedBase::DecidedCompare( const CompareReplace *sr, 00067 const TreePtrInterface &x, 00068 bool can_key, 00069 Conjecture &conj ) 00070 { 00071 INDENT; 00072 string s; 00073 // Keep advancing until we get NULL, and remember the last non-null position 00074 TreePtr<Node> xt = x; 00075 int i = 0; 00076 while( TreePtr<Node> tt = Advance(xt, &s) ) 00077 { 00078 xt = tt; 00079 } 00080 00081 // Compare the last position with the terminus pattern 00082 bool r = sr->DecidedCompare( xt, TreePtr<Node>(terminus), can_key, conj ); 00083 00084 // Compare the depth with the supplied pattern if present 00085 if( r && depth ) 00086 { 00087 TreePtr<Node> cur_depth( new SpecificString(s) ); 00088 r = sr->DecidedCompare( cur_depth, TreePtr<Node>(depth), can_key, conj ); 00089 } 00090 00091 if( r ) 00092 { 00093 // Ensure the replace can terminate and overlay 00094 shared_ptr<TerminusKey> k( new TerminusKey ); 00095 k->root = x; 00096 k->terminus = xt; 00097 return k; 00098 } 00099 else 00100 { 00101 return shared_ptr<Key>(); 00102 } 00103 } 00104 00105 00106 TreePtr<Node> NestedArray::Advance( TreePtr<Node> n, string *depth ) 00107 { 00108 if( TreePtr<Array> a = dynamic_pointer_cast<Array>(n) ) 00109 return a->element; 00110 else 00111 return TreePtr<Node>(); 00112 } 00113 00114 00115 TreePtr<Node> NestedSubscriptLookup::Advance( TreePtr<Node> n, string *depth ) 00116 { 00117 if( TreePtr<Subscript> s = dynamic_pointer_cast<Subscript>(n) ) 00118 { 00119 *depth += "S"; 00120 return s->operands[0]; // the base, not the index 00121 } 00122 else if( TreePtr<Lookup> l = dynamic_pointer_cast<Lookup>(n) ) 00123 { 00124 *depth += "L"; 00125 return l->member; 00126 } 00127 else 00128 { 00129 return TreePtr<Node>(); 00130 } 00131 }