00001 #ifndef __MACROBASE__ 00002 #define __MACROBASE__ 00003 00004 #include <stddef.h> 00005 #include <stdio.h> 00006 #include "common/simple_stack.h" 00007 #include "common/MString.h" 00008 #include "common/ref_counter.h" 00009 00010 #ifndef NULL 00011 #define NULL 0 00012 #endif 00013 00014 // A macro exapnder 00015 // 00016 // 00017 00018 class MacroIter; 00019 00020 class MacroObject; 00021 00022 typedef RCPointer<MacroObject> MacroObjectPtr; 00023 typedef DerivedRCPointer<MacroIter,MacroObjectPtr> MacroIterPtr; 00024 00025 class MacroObject : public RefCountedClass 00026 { 00027 public: 00028 00029 static const LString ClassName; 00030 00031 MacroObject() {} 00032 00033 virtual ~MacroObject() {} 00034 00035 // get the text associated with the object 00036 virtual const String get_text() const = 0; 00037 00038 // return an iterator associated with this object 00039 // If this object is not iterated, just return the object using 00040 // SingleMacroIter. You can also return NULL if there are no objects 00041 // to iterate over (or you can return an iterator with isDone true) 00042 00043 virtual MacroIterPtr get_iter() = 0; 00044 00045 // get a child object. Return NULL if does not exist. 00046 00047 virtual MacroObjectPtr get_child(const LString &name) const {return NULL;} 00048 00049 virtual String child_name_list() const {return String("<none>");} 00050 00051 virtual void Print(int indent = 0) const 00052 { fprintf(stdout,"%s",(const char *)get_text()); } 00053 00054 virtual bool IS_SIMPLE_list() {return false;} 00055 virtual void set_type_name(const LString &) {} 00056 virtual LString get_instance_class_name() const = 0; 00057 virtual LString object_type_name() const { 00058 return get_instance_class_name(); 00059 } 00060 00061 // is_instance_of checks for a kind in the application domain/ This 00062 // is in contradistinction to isKindOf which checks the type 00063 // of the representation (ie, the latter is what kind of macro object) 00064 // 00065 virtual bool is_instance_of(const LString &kind ) const 00066 { return kind == object_type_name();} 00067 static const LString & get_ClassName() {return ClassName;} 00068 virtual bool isKindOf( const LString &kind ) const 00069 { return (kind == ClassName); 00070 } 00071 virtual void perform_final_cleanup() {} 00072 }; 00073 00074 00075 // All classes which are passed to the macro processor must be MacroObjects 00076 00077 // For forall, a MacroIter is required. 00078 00079 class MacroIter : public MacroObject 00080 { 00081 static const LString ClassName; 00082 public: 00083 00084 // get the current object 00085 virtual MacroObjectPtr Item() const = 0; 00086 00087 // move to next, return true if successful 00088 virtual bool Next() = 0; 00089 00090 // are we at end 00091 00092 virtual bool isDone() = 0; 00093 virtual bool isLast() = 0; 00094 virtual int pos() = 0; 00095 00096 virtual const String get_text() const; 00097 00098 // return an iterator associated with this object 00099 // If this object is not iterated, just return the object using 00100 // SingleMacroIter. You can also return NULL if there are no objects 00101 // to iterate over (or you can return an iterator with isDone true) 00102 00103 virtual MacroIterPtr get_iter(); 00104 00105 // get a child object. Return NULL if does not exist. 00106 00107 virtual MacroObjectPtr get_child(const LString &name) const; 00108 00109 virtual String child_name_list() const; 00110 00111 virtual void Print(int indent = 0) const; 00112 00113 virtual LString get_instance_class_name() const { 00114 return ClassName; 00115 } 00116 static const LString & get_ClassName() {return ClassName;} 00117 virtual bool isKindOf( const LString &kind ) const 00118 { return ((kind == ClassName) || MacroObject::isKindOf(kind)); 00119 } 00120 }; 00121 00122 MacroIter * to_MacroIter(MacroObject * ); 00123 00124 // Often, simple_stack objects are iterated over. 00125 // Here is a template of simple_stack base macro iterator 00126 00127 template <class x> class simple_stack_MacroIter : public MacroIter 00128 { 00129 int iter_pos; 00130 const ref_stack<x> list; 00131 public: 00132 simple_stack_MacroIter(const ref_stack<x> &the_list) : iter_pos(0), list(the_list) {} 00133 00134 // note that this is an x not an x *. which means this template can only 00135 // be instantiated with pointer types!!!!! 00136 MacroObjectPtr Item() const 00137 { 00138 if (iter_pos >= list.len()) 00139 return NULL; 00140 return list[iter_pos]; 00141 } 00142 00143 bool Next() 00144 { 00145 iter_pos ++; 00146 if (iter_pos >= list.len()) 00147 { 00148 iter_pos = list.len(); 00149 return false; 00150 } 00151 else 00152 return true; 00153 } 00154 00155 bool isDone() 00156 { 00157 return (iter_pos >= list.len()); 00158 } 00159 00160 bool isLast() 00161 { 00162 return (iter_pos == (list.len() - 1)); 00163 } 00164 00165 int pos() {return iter_pos;} 00166 }; 00167 00168 // You also often want to pass in a null iterator or an iterator with 00169 // exactly one object in it. When a forall is done on an object which is 00170 // not a list, just the object itself should be returned. 00171 00172 class SingleMacroIter : public MacroIter 00173 { 00174 MacroObjectPtr object; 00175 public: 00176 SingleMacroIter(MacroObjectPtr the_object = NULL) 00177 : object(the_object) {} 00178 00179 // note that this is an x not an x *. which means this template can only 00180 // be instantiated with pointer types!!!!! 00181 MacroObjectPtr Item() const {return object;} 00182 00183 bool Next() {object.make_null();return false;} 00184 bool isDone() {return object.is_null();} 00185 bool isLast() {return true;} 00186 00187 int pos() {return 0;} 00188 00189 }; 00190 00191 00192 class AbstractMacroListObject : public MacroObject 00193 { 00194 static const LString ClassName; 00195 00196 protected: 00197 bool is_temp; 00198 00199 public: 00200 00201 AbstractMacroListObject() : is_temp(false) {} 00202 00203 virtual ~AbstractMacroListObject() {} 00204 00205 const String get_text() const {return "";} 00206 00207 virtual void AddObject(MacroObjectPtr object) = 0; 00208 00209 virtual void CutBack(int new_len)=0; 00210 00211 virtual MacroIterPtr get_iter()= 0; 00212 00213 virtual int length() const = 0; 00214 00215 virtual MacroObjectPtr get_item(int i) const = 0; 00216 00217 virtual void Print(int indent = 0) const = 0; 00218 00219 bool get_is_temp() {return is_temp;} 00220 00221 void set_is_temp() {is_temp = true;} 00222 00223 void set_is_not_temp() {is_temp = false;} 00224 00225 virtual void AddObjectList(const AbstractMacroListObject &x) = 0; 00226 00227 virtual void reset()=0; 00228 00229 virtual bool is_simple_list() {return true;} 00230 00231 virtual LString get_instance_class_name() const { 00232 return ClassName; 00233 } 00234 00235 static const LString & get_ClassName() {return ClassName;} 00236 virtual bool isKindOf( const LString &kind ) const 00237 { return ((kind == ClassName) || MacroObject::isKindOf(kind)); 00238 } 00239 00240 00241 MacroObjectPtr get_child(const LString &name) const; 00242 00243 }; 00244 00245 AbstractMacroListObject * to_AbstractMacroListObject(MacroObject* p); 00246 00247 // Only one parameter gets passed in. This has no name. To pass in real parameters, 00248 // you generally want to pass an instance of the following class. The top level name resolution 00249 // will then be done in the class object 00250 00251 00252 class AbstractNamedList : public MacroObject 00253 { 00254 static const LString ClassName; 00255 00256 public: 00257 virtual ~AbstractNamedList(); 00258 00259 virtual String child_name_list() const = 0; 00260 00261 virtual void AddObject(const LString &name, MacroObjectPtr object)= 0; 00262 00263 virtual void CutBack(int new_len)=0; 00264 00265 virtual MacroIterPtr get_iter() = 0; 00266 00267 virtual MacroObjectPtr get_item(int i) const = 0; 00268 00269 virtual void Print(int indent = 0) const = 0; 00270 00271 virtual bool is_simple_list() {return false;} 00272 00273 virtual MacroObjectPtr get_child(const LString &name) const = 0; 00274 00275 virtual int length()const = 0; 00276 00277 virtual LString get_instance_class_name() const { 00278 return ClassName; 00279 } 00280 static const LString & get_ClassName() {return ClassName;} 00281 virtual bool isKindOf( const LString &kind ) const 00282 { return ((kind == ClassName) || MacroObject::isKindOf(kind)); 00283 } 00284 00285 00286 const String get_text() const {return "";} 00287 00288 virtual MacroObjectPtr get_as_list(); 00289 00290 00291 }; 00292 00293 AbstractNamedList * to_AbstractNamedList(MacroObject * ); 00294 00295 00296 // Implementation of the simple string valued macro object 00297 00298 00299 class AbstractStringMacroObject : public MacroObject 00300 { 00301 static const LString ClassName; 00302 00303 public: 00304 00305 virtual MacroIterPtr get_iter() = 0; 00306 00307 // get a child object. Return NULL if does not exist. 00308 00309 virtual void set_text(const String &the_text) = 0; 00310 00311 virtual const String get_text() const = 0; 00312 00313 virtual LString get_instance_class_name() const { 00314 return ClassName; 00315 } 00316 static const LString & get_ClassName() {return ClassName;} 00317 virtual bool isKindOf( const LString &kind ) const 00318 { return ((kind == ClassName) || MacroObject::isKindOf(kind)); 00319 } 00320 00321 }; 00322 00323 AbstractStringMacroObject* to_AbstractStringMacroObject(MacroObject * p); 00324 00325 #endif