00001 #if !defined(CHARMXI_INTERFACE_BUILDER)
00002 #define CHARMXI_INTERFACE_BUILDER
00003
00004 #include <vector>
00005 #include <string>
00006
00007 #include "xi-Type.h"
00008 #include "xi-Parameter.h"
00009 #include "xi-Value.h"
00010 #include "xi-Entry.h"
00011 #include "xi-Chare.h"
00012 #include "xi-Module.h"
00013 #include "constructs/Constructs.h"
00014
00015 namespace Builder {
00016 struct ModuleEntity;
00017 struct MainChare;
00018 struct Chare;
00019
00020 #define NUM_BUILTIN_TYPES 15
00021
00022 const char* builtinTypes[NUM_BUILTIN_TYPES] =
00023 {"int", "long", "short", "char", "unsigned int", "unsigned long",
00024 "unsigned long", "unsigned long long", "unsigned short",
00025 "unsigned char", "long long", "float", "double", "long double",
00026 "void"};
00027
00028 enum BUILDER_ENTRY_ATTRIBUTES
00029 { THREADED = STHREADED,
00030 SYNC = SSYNC,
00031 IGET = SIGET,
00032 EXCLUSIVE = SLOCKED,
00033 CREATEHERE = SCREATEHERE,
00034 CREATEHOME = SCREATEHOME,
00035 NOKEEP = SNOKEEP,
00036 NOTRACE = SNOTRACE,
00037 APPWORK = SAPPWORK,
00038 IMMEDIATE = SIMMEDIATE,
00039 EXPEDITED = SSKIPSCHED,
00040 INLINE = SINLINE,
00041 LOCAL = SLOCAL,
00042 MEMCRITICAL = SMEM,
00043 REDUCTIONTARGET = SREDUCE
00044 };
00045
00046 enum BUILDER_CHARE_ATTRIBUTES
00047 { MIGRATABLE = xi::Chare::CMIGRATABLE };
00048
00049 struct TypeBase {
00050 virtual xi::Type* generateAst() = 0;
00051 };
00052
00053 struct Type : public TypeBase {
00054 char* ident;
00055
00056 Type(char* ident_)
00057 : ident(ident_)
00058 { }
00059
00060 virtual xi::Type* generateAst() {
00061 for (int i = 0; i < NUM_BUILTIN_TYPES; i++)
00062 if (strcmp(ident, builtinTypes[i]) == 0)
00063 return new xi::BuiltinType(ident);
00064 return new xi::NamedType(ident);
00065 }
00066 };
00067
00068 struct PtrType : public TypeBase {
00069 Type* type;
00070 int numstars;
00071
00072 PtrType(Type* type_, int numstars_ = 1)
00073 : type(type_)
00074 , numstars(numstars_)
00075 { }
00076
00077 virtual xi::Type* generateAst() {
00078 xi::PtrType* pt = new xi::PtrType(type->generateAst());
00079 for (int i = 1; i < numstars; i++)
00080 pt->indirect();
00081 return pt;
00082 }
00083 };
00084
00085 struct Value {
00086 char* val;
00087
00088 Value(char* val_ = 0)
00089 : val(val_)
00090 { }
00091
00092 virtual xi::Value* generateAst() {
00093 return new xi::Value(val);
00094 }
00095 };
00096
00097 struct Parameter {
00098 char* name, *array;
00099 TypeBase* type;
00100 Value* val;
00101
00102 Parameter(TypeBase* type_, char* name_ = 0, char* array_ = 0, Value* val_ = 0)
00103 : type(type_)
00104 , name(name_)
00105 , array(array_)
00106 , val(val_)
00107 { }
00108
00109
00110
00111
00112
00113
00114 virtual xi::Parameter* generateAst() {
00115 const int lineno = 0;
00116 return new xi::Parameter(lineno, type->generateAst(), name, array,
00117 val ? val->generateAst() : NULL);
00118 }
00119 };
00120
00121 template<typename Elem, typename List>
00122 struct GenList {
00123 std::vector<Elem*> elems;
00124
00125 virtual List* generateListRecur(int i) {
00126 if (i == elems.size() - 1)
00127 return new List(elems[i]->generateAst());
00128 else
00129 return new List(elems[i]->generateAst(), generateListRecur(i+1));
00130 }
00131 };
00132
00133 template<typename Elem, typename List>
00134 struct GenListLineNo {
00135 std::vector<Elem*> elems;
00136
00137 virtual List* generateListRecurLineNo(int i) {
00138 const int lineno = 0;
00139 if (i == elems.size() - 1)
00140 return new List(lineno, elems[i]->generateAst(), NULL);
00141 else
00142 return new List(lineno, elems[i]->generateAst(), generateListRecurLineNo(i+1));
00143 }
00144 };
00145
00146 struct EntryType : public GenList<Parameter, xi::ParamList> {
00147 void addEntryParameter(Parameter* p) {
00148 elems.push_back(p);
00149 }
00150
00151 xi::ParamList* generateAst() {
00152 return elems.size() > 0 ?
00153 generateListRecur(0) :
00154 new xi::ParamList(new xi::Parameter(0, new xi::BuiltinType("void")));
00155 }
00156 };
00157
00158 namespace SDAG {
00159 struct Construct {
00160 virtual xi::SdagConstruct* generateAst() = 0;
00161 };
00162
00163 struct Serial : public Construct {
00164 char* ccode, *traceName;
00165
00166 Serial(char* ccode_, char* traceName_ = 0)
00167 : ccode(ccode_)
00168 , traceName(traceName_)
00169 { }
00170
00171 virtual xi::SdagConstruct* generateAst() {
00172 const int lineno = 0;
00173 return new xi::SerialConstruct(ccode, traceName, lineno);
00174 }
00175 };
00176
00177 struct Sequence : public Construct, public GenList<Construct, xi::SListConstruct> {
00178 Sequence() { }
00179 Sequence(Construct* c) {
00180 elems.push_back(c);
00181 }
00182
00183 void addConstruct(Construct* c) {
00184 elems.push_back(c);
00185 }
00186
00187 virtual xi::SdagConstruct* generateAst() {
00188 return elems.size() > 0 ? generateListRecur(0) : new xi::SListConstruct(NULL);
00189 }
00190 };
00191
00192 struct Overlap : public GenList<Construct, xi::SListConstruct> {
00193 Overlap() { }
00194
00195 void addConstruct(Construct* c) {
00196 elems.push_back(c);
00197 }
00198
00199 virtual xi::SdagConstruct* generateAst() {
00200 return elems.size() > 0 ? generateListRecur(0) : NULL;
00201 }
00202
00203 virtual xi::OListConstruct* generateOlistRecur(int i) {
00204 if (i == elems.size() - 1)
00205 return new xi::OListConstruct(elems[i]->generateAst());
00206 else
00207 return new xi::OListConstruct(elems[i]->generateAst(), GenList::generateListRecur(i+1));
00208 }
00209 };
00210
00211 struct SEntry : public EntryType {
00212 char* ident, *ref;
00213
00214 SEntry(char* ident_, char* ref_ = 0)
00215 : ident(ident_)
00216 , ref(ref_)
00217 { }
00218
00219 xi::Entry* generateAst() {
00220 const int lineno = 0;
00221 return new xi::Entry(lineno, 0,
00222 new xi::BuiltinType("void"),
00223 ident,
00224 EntryType::generateAst(), 0, 0, ref);
00225 }
00226 };
00227
00228 template<typename T>
00229 struct WhenTemp : public Construct, public GenList<SEntry, xi::EntryList> {
00230 Sequence* seq;
00231
00232 void addSEntry(SEntry* c) {
00233 elems.push_back(c);
00234 }
00235
00236 WhenTemp(Sequence* seq_)
00237 : seq(seq_)
00238 { }
00239
00240 virtual xi::SdagConstruct* generateAst() {
00241 return new T(elems.size() > 0 ? generateListRecur(0) : NULL, seq->generateAst());
00242 }
00243 };
00244
00245 typedef WhenTemp<xi::WhenConstruct> When;
00246 typedef WhenTemp<xi::CaseConstruct> Case;
00247
00248 struct Else : public Construct {
00249 Construct* cons;
00250
00251 Else(Construct* cons_)
00252 : cons(cons_)
00253 { }
00254
00255 virtual xi::SdagConstruct* generateAst() {
00256 return new xi::ElseConstruct(cons->generateAst());
00257 }
00258 };
00259
00260 struct If : public Construct {
00261 char* cond;
00262 Construct* cons;
00263 Else* el;
00264
00265 If(char* cond_, Construct* cons_, Else* el_)
00266 : cond(cond_)
00267 , cons(cons_)
00268 , el(el_)
00269 { }
00270
00271 virtual xi::SdagConstruct* generateAst() {
00272 return new xi::IfConstruct(new xi::IntExprConstruct(cond),
00273 cons->generateAst(),
00274 el ? el->generateAst() : NULL);
00275 }
00276 };
00277
00278 struct While : public Construct {
00279 char* cond;
00280 Construct* cons;
00281
00282 While(char* cond_, Construct* cons_)
00283 : cond(cond_)
00284 , cons(cons_)
00285 { }
00286
00287 virtual xi::SdagConstruct* generateAst() {
00288 return new xi::WhileConstruct(new xi::IntExprConstruct(cond),
00289 cons->generateAst());
00290 }
00291 };
00292
00293 struct For : public Construct {
00294 char* decl, *pred, *advance;
00295 Construct* cons;
00296
00297 For(char* decl_, char* pred_, char* advance_, Construct* cons_)
00298 : decl(decl_)
00299 , pred(pred_)
00300 , advance(advance_)
00301 , cons(cons_)
00302 { }
00303
00304 virtual xi::SdagConstruct* generateAst() {
00305 return new xi::ForConstruct(new xi::IntExprConstruct(decl),
00306 new xi::IntExprConstruct(pred),
00307 new xi::IntExprConstruct(advance),
00308 cons->generateAst());
00309 }
00310 };
00311
00312 struct ForAll : public Construct {
00313 char* ident;
00314 char* begin, *end, *step;
00315 Construct* cons;
00316
00317 ForAll(char* ident_, char* begin_, char* end_, char* step_, Construct* cons_)
00318 : ident(ident_)
00319 , begin(begin_)
00320 , end(end_)
00321 , step(step_)
00322 , cons(cons_)
00323 { }
00324
00325 virtual xi::SdagConstruct* generateAst() {
00326 return new xi::ForallConstruct(new xi::SdagConstruct(xi::SIDENT, ident),
00327 new xi::IntExprConstruct(begin),
00328 new xi::IntExprConstruct(end),
00329 new xi::IntExprConstruct(step),
00330 cons->generateAst());
00331 }
00332 };
00333 }
00334
00335 struct Entry : public EntryType {
00336 Type* ret;
00337 char *name;
00338 Value* stackSize;
00339 int eattrib;
00340 SDAG::Construct* sdag;
00341
00342 void addSDAG(SDAG::Construct* sdag_) {
00343 sdag = sdag_;
00344 }
00345
00346 Entry(Type* ret_, char* name_, Value* stackSize_ = 0, SDAG::Construct* sdag_ = 0)
00347 : ret(ret_)
00348 , name(name_)
00349 , stackSize(stackSize_)
00350 , eattrib(0)
00351 , sdag(sdag_)
00352 { }
00353
00354 void addAttribute(BUILDER_ENTRY_ATTRIBUTES attribute) {
00355 eattrib |= attribute;
00356 }
00357
00358 xi::Entry* generateAst() {
00359 const int lineno = 0;
00360 xi::SdagConstruct* scons = NULL;
00361 if (sdag) scons = new xi::SdagEntryConstruct(sdag->generateAst());
00362 xi::ParamList* pl = EntryType::generateAst();
00363 xi::Entry* entry = new xi::Entry(lineno,
00364 eattrib,
00365 ret ? ret->generateAst() : NULL,
00366 name,
00367 pl,
00368 stackSize ? stackSize->generateAst() : NULL,
00369 scons);
00370 if (sdag) {
00371 scons->con1 = new xi::SdagConstruct(xi::SIDENT, name);
00372 scons->setEntry(entry);
00373 scons->con1->setEntry(entry);
00374 scons->param = pl;
00375 }
00376 return entry;
00377 }
00378
00379 };
00380
00381 struct ModuleEntity : public GenListLineNo<Entry, xi::AstChildren<xi::Member> > {
00382 int attrib;
00383 std::vector<char*> baseList;
00384 xi::TParamList *tparams;
00385
00386 ModuleEntity()
00387 : attrib(0)
00388 , tparams(NULL)
00389 { }
00390
00391 void addEntry(Entry* et) {
00392 elems.push_back(et);
00393 }
00394
00395 void addBaseType(char* b) {
00396 baseList.push_back(b);
00397 }
00398
00399 void addTParam(char* name, bool builtin = false) {
00400 xi::Type* ty = builtin ? (xi::Type*) new xi::BuiltinType(name) : (xi::Type*) new xi::NamedType(name);
00401 tparams = new xi::TParamList(new xi::TParamType(ty), tparams);
00402 }
00403
00404 xi::TypeList* generateBaseList() {
00405 return baseList.size() > 0 ? generateBaseListRecur(0) : NULL;
00406 }
00407
00408 xi::TypeList* generateBaseListRecur(int i) {
00409 if (i == baseList.size() - 1)
00410 return new xi::TypeList(new xi::NamedType(baseList[i]));
00411 else
00412 return new xi::TypeList(new xi::NamedType(baseList[i]), generateBaseListRecur(i+1));
00413 }
00414
00415 xi::AstChildren<xi::Member>* generateChildren() {
00416 return elems.size() > 0 ? generateListRecurLineNo(0) : NULL;
00417 }
00418
00419 virtual int generateAttributes(int attrib) = 0;
00420 virtual xi::Construct* generateAst() = 0;
00421 };
00422
00423 struct Module : public GenListLineNo<ModuleEntity, xi::ConstructList> {
00424 char* name;
00425 bool isMain;
00426
00427 Module(char* _name, bool isMain_)
00428 : name(_name)
00429 , isMain(isMain_)
00430 { }
00431
00432 void addModuleEntity(ModuleEntity* mcb) {
00433 elems.push_back(mcb);
00434 }
00435
00436 xi::Module* generateAst() {
00437 const int lineno = 0;
00438 xi::Module* mod = new xi::Module(lineno, name,
00439 elems.size() > 0 ? generateListRecurLineNo(0) : NULL);
00440 if (isMain) mod->setMain();
00441 return mod;
00442 }
00443 };
00444
00445 struct File : public GenListLineNo<Module, xi::AstChildren<xi::Module> > {
00446 File() {}
00447
00448 void addModule(Module* m) {
00449 elems.push_back(m);
00450 }
00451
00452 xi::AstChildren<xi::Module>* generateAst() {
00453 return elems.size() > 0 ? generateListRecurLineNo(0) : NULL;
00454 }
00455 };
00456
00457 struct Readonly : public ModuleEntity {
00458 Type* type;
00459 char* name;
00460
00461
00462 Readonly(Type* type_, char* name_)
00463 : ModuleEntity()
00464 , type(type_)
00465 , name(name_)
00466 { }
00467
00468 virtual int generateAttributes(int attrib) {
00469 return attrib;
00470 }
00471
00472 virtual xi::Construct* generateAst() {
00473 const int lineno = 0;
00474 return new xi::Readonly(lineno,
00475 type->generateAst(),
00476 name,
00477 NULL);
00478 }
00479 };
00480
00481 struct MainChare : public ModuleEntity {
00482 char* name;
00483
00484 MainChare(char* _name)
00485 : ModuleEntity()
00486 , name(_name) { }
00487
00488 virtual int generateAttributes(int attrib) {
00489 return attrib | xi::Chare::CMAINCHARE;
00490 }
00491
00492 virtual xi::Construct* generateAst() {
00493 const int lineno = 0;
00494 return new xi::MainChare(lineno,
00495 this->generateAttributes(attrib),
00496 new xi::NamedType(name, tparams),
00497 ModuleEntity::generateBaseList(),
00498 ModuleEntity::generateChildren());
00499 }
00500 };
00501
00502 struct Chare : public ModuleEntity {
00503 char* name;
00504
00505 Chare(char* _name)
00506 : ModuleEntity()
00507 , name(_name)
00508 { }
00509
00510 virtual int generateAttributes(int attrib) {
00511 return attrib | xi::Chare::CCHARE;
00512 }
00513
00514 virtual xi::Construct* generateAst() {
00515 const int lineno = 0;
00516 return new xi::Chare(lineno,
00517 this->generateAttributes(attrib),
00518 new xi::NamedType(name, tparams),
00519 ModuleEntity::generateBaseList(),
00520 ModuleEntity::generateChildren());
00521 }
00522 };
00523
00524 struct Group : public ModuleEntity {
00525 char* name;
00526
00527 Group(char* _name)
00528 : ModuleEntity()
00529 , name(_name)
00530 { }
00531
00532 virtual int generateAttributes(int attrib) {
00533 return attrib | xi::Chare::CGROUP;
00534 }
00535
00536 virtual xi::Construct* generateAst() {
00537 const int lineno = 0;
00538 return new xi::Group(lineno,
00539 this->generateAttributes(attrib),
00540 new xi::NamedType(name, tparams),
00541 ModuleEntity::generateBaseList(),
00542 ModuleEntity::generateChildren());
00543 }
00544 };
00545
00546 struct NodeGroup : public ModuleEntity {
00547 char* name;
00548
00549 NodeGroup(char* _name)
00550 : ModuleEntity()
00551 , name(_name)
00552 { }
00553
00554 virtual int generateAttributes(int attrib) {
00555 return attrib | xi::Chare::CGROUP;
00556 }
00557
00558 virtual xi::Construct* generateAst() {
00559 const int lineno = 0;
00560 return new xi::NodeGroup(lineno,
00561 this->generateAttributes(attrib),
00562 new xi::NamedType(name, tparams),
00563 ModuleEntity::generateBaseList(),
00564 ModuleEntity::generateChildren());
00565 }
00566 };
00567
00568 struct Array : public ModuleEntity {
00569 char* name, *index;
00570
00571 Array(char* name_, char* index_)
00572 : ModuleEntity()
00573 , name(name_)
00574 , index(index_)
00575 { }
00576
00577 virtual int generateAttributes(int attrib) {
00578 return attrib | xi::Chare::CARRAY;
00579 }
00580
00581 virtual xi::Construct* generateAst() {
00582 const int lineno = 0;
00583 return new xi::Array(lineno,
00584 this->generateAttributes(attrib),
00585 new xi::NamedType(index),
00586 new xi::NamedType(name, tparams),
00587 ModuleEntity::generateBaseList(),
00588 ModuleEntity::generateChildren());
00589 }
00590 };
00591
00592 struct MessageVar {
00593 char *name;
00594 char *type;
00595
00596 MessageVar *next;
00597
00598 MessageVar(char *name_, char *type_)
00599 : name(name_), type(type_), next(NULL)
00600 { }
00601
00602 xi::MsgVarList* generateAst() {
00603 xi::MsgVar *mv = new xi::MsgVar(new xi::NamedType(type), name, false, false);
00604 return new xi::MsgVarList(mv, next ? next->generateAst() : NULL);
00605 }
00606 };
00607
00608 struct Message : public ModuleEntity {
00609 char *name;
00610 MessageVar* lst;
00611
00612 Message(char *name_)
00613 : ModuleEntity()
00614 , name(name_)
00615 , lst(NULL)
00616 { }
00617
00618 virtual int generateAttributes(int attrib) {
00619 return attrib;
00620 }
00621
00622 void addMessageVar(char *type, char *name) {
00623 addMessageVar(new MessageVar(name, type));
00624 }
00625
00626 void addMessageVar(MessageVar* nxt) {
00627 if (lst) lst->next = nxt;
00628 lst = nxt;
00629 }
00630
00631 virtual xi::Construct* generateAst() {
00632 const int lineno = 0;
00633 xi::MsgVarList *mv = lst ? lst->generateAst() : NULL;
00634 return new xi::Message(lineno, new xi::NamedType(name), mv);
00635 }
00636 };
00637
00638 struct InitCall : public ModuleEntity {
00639 char *name;
00640 int isNode;
00641
00642 InitCall(char* name_, int isNode_)
00643 : ModuleEntity()
00644 , name(name_)
00645 , isNode(isNode_)
00646 { }
00647
00648 virtual int generateAttributes(int attrib) {
00649 return attrib;
00650 }
00651
00652 virtual xi::Construct* generateAst() {
00653 const int lineno = 0;
00654 return new xi::InitCall(lineno, name, isNode);
00655 }
00656 };
00657
00658 struct ConsEntry : public Entry {
00659 ConsEntry(char* name_)
00660 : Entry(NULL, name_)
00661 { }
00662 };
00663 }
00664
00665 #endif