00001 //===-- ast/AstRewriter.h ------------------------------------- -*- C++ -*-===// 00002 // 00003 // This file is distributed under the MIT license. See LICENSE.txt for details. 00004 // 00005 // Copyright (C) 2008, Stephen Wilson 00006 // 00007 //===----------------------------------------------------------------------===// 00008 // 00009 // This class implements a map from one set of nodes to another. In some ways, 00010 // it is like a scope where the components of an AST can be resolved with 00011 // respect to the "bindings" established in the rewriter. For example, the 00012 // AstRewriter can encapsulate the mappings from the formal to actual parameters 00013 // of a functor, or from a % node to a concrete domain type. 00014 // 00015 // Methods are provided to build and interrogate the set of mappings, and to 00016 // create new nodes using a set of mappings. 00017 // 00018 //===----------------------------------------------------------------------===// 00019 00020 #ifndef COMMA_AST_ASTREWRITER_HDR_GUARD 00021 #define COMMA_AST_ASTREWRITER_HDR_GUARD 00022 00023 #include "comma/ast/AstBase.h" 00024 #include <map> 00025 00026 namespace comma { 00027 00028 class AstRewriter { 00029 00030 public: 00031 // Adds a rewrite rule from the source to target. If a mapping from the 00032 // given source already exists, this method will unconditionally re-target 00033 // the rule to the given source -- it is the responsibility of the 00034 // programmer to ensure that established rules are not mistakenly 00035 // overwritten. 00036 void addRewrite(DomainType *source, DomainType *target) { 00037 rewrites[source] = target; 00038 } 00039 00040 // Maps source to a target if a rewrite rule exists, otherwise returns 00041 // source. 00042 DomainType *getRewrite(DomainType *source) const; 00043 00044 // Returns a reference to a target entry in the rewriter corresponding to 00045 // source. This returned value is an lvalue and can be used as a shorthand 00046 // for addRewrite. 00047 DomainType *&operator [](DomainType *source) { 00048 return rewrites[source]; 00049 } 00050 00051 // Populates this rewriter with rules which map the formal argument nodes of 00052 // the underlying declaration to the actual arguments provided by the 00053 // supplied type. In addition, a mapping from the % node of the declaration 00054 // to the given type is established. The only case in which this method is 00055 // a no-op is when the supplied type is a PercentType. 00056 void installRewrites(DomainType *context); 00057 00058 // Populates this rewriter with rules which map the formal argument nodes of 00059 // the underlying signature declaration to the actual arguments provided by 00060 // the type. This method is a no-op when the supplied type is not 00061 // parameterized. 00062 void installRewrites(SignatureType *context); 00063 00064 // Returns true if the given type is rewritten to a distinct node using the 00065 // established rules. 00066 bool isRewriteSource(DomainType *source) const { 00067 return getRewrite(source) != source; 00068 } 00069 00070 // Remove all rewrite rules. 00071 void clear() { rewrites.clear(); } 00072 00073 // Rewrites the given signature type according to the installed rules. 00074 SignatureType *rewrite(SignatureType *sig) const; 00075 00076 // Rewrites the given domain type according to the installed rules. 00077 DomainType *rewrite(DomainType *dom) const; 00078 00079 // Rewrites the given function type according to the installed rules. 00080 // 00081 // FIXME: Currently, a freshly `newed' node is unconditionally created, even 00082 // in the case where no rewrites were applicable. This behaviour will 00083 // change once the allocation requirements of function type nodes are nailed 00084 // down. 00085 FunctionType *rewrite(FunctionType *ftype) const; 00086 00087 private: 00088 typedef std::map<DomainType*, DomainType*> RewriteMap; 00089 RewriteMap rewrites; 00090 }; 00091 00092 } // End comma namespace 00093 00094 #endif