Inferno  0.2
inferno_patterns.cpp
Go to the documentation of this file.
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 }