00001 #ifndef _AST_NODE_H
00002 #define _AST_NODE_H
00003
00004 #include "xi-util.h"
00005 #include <algorithm>
00006 #include <list>
00007
00008 namespace xi {
00009
00010 class AstNode : public Printable {
00011 protected:
00012 int line;
00013
00014 public:
00015 explicit AstNode(int line_ = -1) : line(line_) {}
00016 virtual void outputClosuresDecl(XStr& str) { (void)str; }
00017 virtual void outputClosuresDef(XStr& str) { (void)str; }
00018 virtual void genDecls(XStr& str) { (void)str; }
00019 virtual void genDefs(XStr& str) { (void)str; }
00020 virtual void genClosureEntryDecls(XStr& str) {}
00021 virtual void genClosureEntryDefs(XStr& str) {}
00022 virtual void genReg(XStr& str) { (void)str; }
00023 virtual void genGlobalCode(XStr scope, XStr& decls, XStr& defs) {
00024 (void)scope;
00025 (void)decls;
00026 (void)defs;
00027 }
00028 virtual void preprocess() {}
00029 virtual void check() {}
00030 virtual void printChareNames() {}
00031
00032 virtual void genTramTypes() {}
00033 virtual void genTramRegs(XStr& str) { (void)str; }
00034 virtual void genTramPups(XStr& scope, XStr& decls, XStr& defs) {
00035 (void)scope;
00036 (void)decls;
00037 (void)defs;
00038 }
00039
00040
00041 virtual int genAccels_spe_c_funcBodies(XStr& str) {
00042 (void)str;
00043 return 0;
00044 }
00045 virtual void genAccels_spe_c_regFuncs(XStr& str) { (void)str; }
00046 virtual void genAccels_spe_c_callInits(XStr& str) { (void)str; }
00047 virtual void genAccels_spe_h_includes(XStr& str) { (void)str; }
00048 virtual void genAccels_spe_h_fiCountDefs(XStr& str) { (void)str; }
00049 virtual void genAccels_ppe_c_regFuncs(XStr& str) { (void)str; }
00050 };
00051
00052 template <typename Child>
00053 class AstChildren : public virtual AstNode {
00054 protected:
00055 std::list<Child*> children;
00056
00057 public:
00058 AstChildren(int line_, Child* c, AstChildren* cs) : AstNode(line_) {
00059 children.push_back(c);
00060 if (cs) children.insert(children.end(), cs->children.begin(), cs->children.end());
00061 }
00062
00063 template <typename T>
00064 explicit AstChildren(std::list<T*>& l) {
00065 children.insert(children.begin(), l.begin(), l.end());
00066 l.clear();
00067 }
00068 void push_back(Child* c);
00069
00070 void preprocess();
00071 void check();
00072 void print(XStr& str);
00073
00074 void printChareNames();
00075
00076 void outputClosuresDecl(XStr& str);
00077 void outputClosuresDef(XStr& str);
00078
00079 void genClosureEntryDecls(XStr& str);
00080 void genClosureEntryDefs(XStr& str);
00081 void genDecls(XStr& str);
00082 void genDefs(XStr& str);
00083 void genReg(XStr& str);
00084 void genGlobalCode(XStr scope, XStr& decls, XStr& defs);
00085
00086 bool isTramTarget();
00087 void genTramTypes();
00088 void genTramRegs(XStr& str);
00089 void genTramPups(XStr& scope, XStr& decls, XStr& defs);
00090
00091
00092 int genAccels_spe_c_funcBodies(XStr& str);
00093 void genAccels_spe_c_regFuncs(XStr& str);
00094 void genAccels_spe_c_callInits(XStr& str);
00095 void genAccels_spe_h_includes(XStr& str);
00096 void genAccels_spe_h_fiCountDefs(XStr& str);
00097 void genAccels_ppe_c_regFuncs(XStr& str);
00098
00099 template <typename T>
00100 void recurse(T arg, void (Child::*fn)(T));
00101 void recursev(void (Child::*fn)());
00102 };
00103
00104 namespace details {
00105 using std::list;
00106 using std::for_each;
00107
00113 template <typename T, typename U, typename A>
00114 class perElemGenC {
00115 void (U::*fn)(A);
00116 void (*between)(A);
00117 A arg;
00118
00119 public:
00120 perElemGenC(list<T*>& l, A arg_, void (U::*fn_)(A), void (*between_)(A) = NULL)
00121 : fn(fn_), between(between_), arg(arg_) {
00122 for_each(l.begin(), l.end(), *this);
00123 }
00124 void operator()(T* m) {
00125 if (m) {
00126 (m->*fn)(arg);
00127 if (between) between(arg);
00128 }
00129 }
00130 };
00131
00132 template <typename T, typename U, typename A>
00133 void perElemGen(list<T*>& l, A& arg_, void (U::*fn_)(A&),
00134
00135
00136 void (*between_)(A&)) {
00137 perElemGenC<T, U, A&>(l, arg_, fn_, between_);
00138 }
00139
00140 template <typename T, typename U, typename A>
00141 void perElemGen(list<T*>& l, A& arg_, void (U::*fn_)(A&)) {
00142 perElemGenC<T, U, A&>(l, arg_, fn_, NULL);
00143 }
00144
00145 template <typename T, typename U, typename A>
00146 void perElemGen(list<T*>& l, A* arg_, void (U::*fn_)(A*),
00147
00148
00149 void (*between_)(A*)) {
00150 perElemGenC<T, U, A*>(l, arg_, fn_, between_);
00151 }
00152
00153 template <typename T, typename U, typename A>
00154 void perElemGen(list<T*>& l, A* arg_, void (U::*fn_)(A*)) {
00155 perElemGenC<T, U, A*>(l, arg_, fn_, NULL);
00156 }
00157
00163 template <typename T, typename U, typename A>
00164 class perElemGen2C {
00165 void (U::*fn)(A, A);
00166 void (*between)(A, A);
00167 A arg1, arg2;
00168
00169 public:
00170 perElemGen2C(list<T*>& l, A arg1_, A arg2_, void (U::*fn_)(A, A),
00171 void (*between_)(A, A) = NULL)
00172 : fn(fn_), between(between_), arg1(arg1_), arg2(arg2_) {
00173 for_each(l.begin(), l.end(), *this);
00174 }
00175 void operator()(T* m) {
00176 if (m) {
00177 (m->*fn)(arg1, arg2);
00178 if (between) between(arg1, arg2);
00179 }
00180 }
00181 };
00182
00183 template <typename T, typename U, typename A>
00184 void perElemGen2(list<T*>& l, A& arg1_, A& arg2_, void (U::*fn_)(A&, A&),
00185
00186
00187 void (*between_)(A&, A&)) {
00188 perElemGen2C<T, U, A&>(l, arg1_, arg2_, fn_, between_);
00189 }
00190
00191 template <typename T, typename U, typename A>
00192 void perElemGen2(list<T*>& l, A& arg1_, A& arg2_, void (U::*fn_)(A&, A&)) {
00193 perElemGen2C<T, U, A&>(l, arg1_, arg2_, fn_, NULL);
00194 }
00195
00196 template <typename T, typename U, typename A>
00197 void perElemGen2(list<T*>& l, A* arg1_, A* arg2_, void (U::*fn_)(A*, A*),
00198
00199
00200 void (*between_)(A*, A*)) {
00201 perElemGen2C<T, U, A*>(l, arg1_, arg2_, fn_, between_);
00202 }
00203
00204 template <typename T, typename U, typename A>
00205 void perElemGen2(list<T*>& l, A* arg1_, A* arg2_, void (U::*fn_)(A*, A*)) {
00206 perElemGen2C<T, U, A*>(l, arg1_, arg2_, fn_, NULL);
00207 }
00208
00213 template <typename T, typename U>
00214 class perElemC {
00215 void (U::*fn)();
00216
00217 public:
00218 perElemC(list<T*>& l, void (U::*fn_)()) : fn(fn_) {
00219 for_each(l.begin(), l.end(), *this);
00220 }
00221 void operator()(T* m) {
00222 if (m) {
00223 (m->*fn)();
00224 }
00225 }
00226 };
00227
00228 template <typename T, typename U>
00229 void perElem(list<T*>& l, void (U::*fn_)()) {
00230 perElemC<T, U>(l, fn_);
00231 }
00232
00233 void newLine(XStr& str);
00234 }
00235
00236 template <typename Child>
00237 void AstChildren<Child>::push_back(Child* m) {
00238 children.push_back(m);
00239 }
00240
00241 template <typename Child>
00242 void AstChildren<Child>::print(XStr& str) {
00243 details::perElemGen(children, str, &Child::print);
00244 }
00245
00246 template <typename Child>
00247 void AstChildren<Child>::preprocess() {
00248 details::perElem(children, &Child::preprocess);
00249 }
00250
00251 template <typename Child>
00252 void AstChildren<Child>::check() {
00253 details::perElem(children, &Child::check);
00254 }
00255
00256 template <typename Child>
00257 void AstChildren<Child>::genDecls(XStr& str) {
00258 details::perElemGen(children, str, &Child::genDecls, details::newLine);
00259 }
00260
00261 template <typename Child>
00262 void AstChildren<Child>::genClosureEntryDecls(XStr& str) {
00263 details::perElemGen(children, str, &Child::genClosureEntryDecls, details::newLine);
00264 }
00265
00266 template <typename Child>
00267 void AstChildren<Child>::genClosureEntryDefs(XStr& str) {
00268 details::perElemGen(children, str, &Child::genClosureEntryDefs, details::newLine);
00269 }
00270
00271 template <typename Child>
00272 void AstChildren<Child>::outputClosuresDecl(XStr& str) {
00273 details::perElemGen(children, str, &Child::outputClosuresDecl, details::newLine);
00274 }
00275
00276 template <typename Child>
00277 void AstChildren<Child>::outputClosuresDef(XStr& str) {
00278 details::perElemGen(children, str, &Child::outputClosuresDef, details::newLine);
00279 }
00280
00281 template <typename Child>
00282 void AstChildren<Child>::genDefs(XStr& str) {
00283 details::perElemGen(children, str, &Child::genDefs, details::newLine);
00284 }
00285
00286 template <typename Child>
00287 void AstChildren<Child>::genReg(XStr& str) {
00288 details::perElemGen(children, str, &Child::genReg, details::newLine);
00289 }
00290
00291 template <typename Child>
00292 template <typename T>
00293 void AstChildren<Child>::recurse(T t, void (Child::*fn)(T)) {
00294 details::perElemGen(children, t, fn);
00295 }
00296
00297 template <typename Child>
00298 void AstChildren<Child>::recursev(void (Child::*fn)()) {
00299 details::perElem(children, fn);
00300 }
00301
00302 template <typename Child>
00303 void AstChildren<Child>::genGlobalCode(XStr scope, XStr& decls, XStr& defs) {
00304 for (typename std::list<Child*>::iterator i = children.begin(); i != children.end();
00305 ++i) {
00306 if (*i) {
00307 (*i)->genGlobalCode(scope, decls, defs);
00308 }
00309 }
00310 }
00311
00312 template <typename Child>
00313 void AstChildren<Child>::printChareNames() {
00314 details::perElem(children, &Child::printChareNames);
00315 }
00316
00317 template <typename Child>
00318 bool AstChildren<Child>::isTramTarget() {
00319 for (typename std::list<Child*>::iterator i = children.begin(); i != children.end();
00320 ++i)
00321 if ((*i)->isTramTarget()) return true;
00322
00323 return false;
00324 }
00325
00326 template <typename Child>
00327 void AstChildren<Child>::genTramTypes() {
00328 details::perElem(children, &Child::genTramTypes);
00329 }
00330
00331 template <typename Child>
00332 void AstChildren<Child>::genTramRegs(XStr& str) {
00333 details::perElemGen(children, str, &Child::genTramRegs);
00334 }
00335
00336 template <typename Child>
00337 void AstChildren<Child>::genTramPups(XStr& scope, XStr& decls, XStr& defs) {
00338 for (typename std::list<Child*>::iterator i = children.begin(); i != children.end();
00339 ++i) {
00340 if (*i) {
00341 (*i)->genTramPups(scope, decls, defs);
00342 }
00343 }
00344 }
00345
00346 template <typename Child>
00347 int AstChildren<Child>::genAccels_spe_c_funcBodies(XStr& str) {
00348 int rtn = 0;
00349 for (typename std::list<Child*>::iterator i = children.begin(); i != children.end();
00350 ++i) {
00351 if (*i) {
00352 rtn += (*i)->genAccels_spe_c_funcBodies(str);
00353 }
00354 }
00355 return rtn;
00356 }
00357
00358 template <typename Child>
00359 void AstChildren<Child>::genAccels_spe_c_regFuncs(XStr& str) {
00360 details::perElemGen(children, str, &Child::genAccels_spe_c_regFuncs);
00361 }
00362
00363 template <typename Child>
00364 void AstChildren<Child>::genAccels_spe_c_callInits(XStr& str) {
00365 details::perElemGen(children, str, &Child::genAccels_spe_c_callInits);
00366 }
00367
00368 template <typename Child>
00369 void AstChildren<Child>::genAccels_spe_h_includes(XStr& str) {
00370 details::perElemGen(children, str, &Child::genAccels_spe_h_includes);
00371 }
00372
00373 template <typename Child>
00374 void AstChildren<Child>::genAccels_spe_h_fiCountDefs(XStr& str) {
00375 details::perElemGen(children, str, &Child::genAccels_spe_h_fiCountDefs);
00376 }
00377
00378 template <typename Child>
00379 void AstChildren<Child>::genAccels_ppe_c_regFuncs(XStr& str) {
00380 details::perElemGen(children, str, &Child::genAccels_ppe_c_regFuncs);
00381 }
00382
00383 }
00384
00385 #endif // ifndef _AST_NODE_H