Michael Uleysky
9 years ago
6 changed files with 193 additions and 135 deletions
@ -0,0 +1,145 @@ |
|||||||
|
#include "deptree.h" |
||||||
|
#include "globals.h" |
||||||
|
|
||||||
|
int DepTree::CreateNodeFromVar(const std::string& var, std::set<std::string>& used, std::set<DepTree*>& callstack) |
||||||
|
{ |
||||||
|
COUT(DEBUG)<<"DepTree::CreateNodeFromVar "<<var<<std::endl; |
||||||
|
if(G_vars.count(var)==0) |
||||||
|
{ |
||||||
|
COUT(ERROR)<<"Definition of variable "<<var<<" not found"<<std::endl; |
||||||
|
return 1; |
||||||
|
} |
||||||
|
|
||||||
|
std::set<std::string> ids; |
||||||
|
|
||||||
|
used.insert(var); |
||||||
|
G_vars[var]->UsedIdents(ids); |
||||||
|
type=DepTree::VAR; |
||||||
|
name=var; |
||||||
|
|
||||||
|
DepTree* d; |
||||||
|
int ret; |
||||||
|
callstack.insert(this); |
||||||
|
for(auto& i:ids) |
||||||
|
{ |
||||||
|
d=FindNodeByVar(i); |
||||||
|
if(d==0) |
||||||
|
{ |
||||||
|
auto n=*childrens.insert(new DepTree).first; |
||||||
|
n->parents.insert(this); |
||||||
|
ret=n->CreateNodeFromVar(i,used,callstack); |
||||||
|
if(ret!=0) |
||||||
|
{ |
||||||
|
COUT(ERROR)<<" in definition of variable "<<name<<std::endl; |
||||||
|
return ret; |
||||||
|
} |
||||||
|
} |
||||||
|
else |
||||||
|
{ |
||||||
|
if(callstack.find(d)!=callstack.end()) |
||||||
|
{ |
||||||
|
COUT(ERROR)<<"Circular dependency of variable "<<name<<" from variable "<<i<<std::endl; |
||||||
|
return 1; |
||||||
|
} |
||||||
|
childrens.insert(d); |
||||||
|
d->parents.insert(this); |
||||||
|
} |
||||||
|
} |
||||||
|
callstack.erase(this); |
||||||
|
|
||||||
|
return 0; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
int DepTree::CreateNodeFromSP(DepTree::NodeType list, std::vector<ObjectList*>::size_type ind, std::set<std::string>& used) |
||||||
|
{ |
||||||
|
if(list!=DepTree::SAVE && list!=DepTree::PRINT) |
||||||
|
{ |
||||||
|
COUT(ERROR)<<"Internal error, incorrect NodeType in DepTree::CreateNodeFromSP()."<<std::endl; |
||||||
|
return 2; |
||||||
|
} |
||||||
|
COUT(DEBUG)<<"DepTree::CreateNodeFromSP "<<((list==DepTree::SAVE)?G_tosave:G_toprint)[ind]->Dump()<<std::endl; |
||||||
|
|
||||||
|
std::set<std::string> ids; |
||||||
|
std::set<DepTree*> callstack; |
||||||
|
|
||||||
|
type=list; |
||||||
|
index=ind; |
||||||
|
|
||||||
|
if(type==DepTree::SAVE) G_tosave[index]->UsedIdents(ids); |
||||||
|
else if(type==DepTree::PRINT) G_toprint[index]->UsedIdents(ids); |
||||||
|
DepTree* d; |
||||||
|
int ret; |
||||||
|
for(auto& i:ids) |
||||||
|
{ |
||||||
|
d=FindNodeByVar(i); |
||||||
|
if(d==0) |
||||||
|
{ |
||||||
|
auto n=*childrens.insert(new DepTree).first; |
||||||
|
n->parents.insert(this); |
||||||
|
ret=n->CreateNodeFromVar(i,used,callstack); |
||||||
|
if(ret!=0) |
||||||
|
{ |
||||||
|
COUT(ERROR)<<" in "<<((type==DepTree::SAVE)?"save":"print")<<" directive "<<((type==DepTree::SAVE)?G_tosave:G_toprint)[index]->Dump()<<"."<<std::endl; |
||||||
|
return ret; |
||||||
|
} |
||||||
|
} |
||||||
|
else |
||||||
|
{ |
||||||
|
childrens.insert(d); |
||||||
|
d->parents.insert(this); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return 0; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
int DepTree::CreateGlobalTree(std::set<std::string>& used) |
||||||
|
{ |
||||||
|
if(parents.size()!=0) |
||||||
|
{ |
||||||
|
COUT(ERROR)<<"Internal error, DepTree::CreateGlobalTree() call for non-root node."<<std::endl; |
||||||
|
return 2; |
||||||
|
} |
||||||
|
|
||||||
|
type=DepTree::ROOT; |
||||||
|
for(int i=0; i<G_tosave.size(); i++) |
||||||
|
{ |
||||||
|
auto n=*childrens.insert(new DepTree).first; |
||||||
|
n->parents.insert(this); |
||||||
|
auto ret=n->CreateNodeFromSP(DepTree::SAVE,i,used); |
||||||
|
if(ret!=0) return ret; |
||||||
|
} |
||||||
|
for(int i=0; i<G_toprint.size(); i++) |
||||||
|
{ |
||||||
|
auto n=*childrens.insert(new DepTree).first; |
||||||
|
n->parents.insert(this); |
||||||
|
auto ret=n->CreateNodeFromSP(DepTree::PRINT,i,used); |
||||||
|
if(ret!=0) return ret; |
||||||
|
} |
||||||
|
|
||||||
|
return 0; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
DepTree* DepTree::FindNodeByVarFromCurrent(const std::string& var) const |
||||||
|
{ |
||||||
|
if(type==DepTree::VAR && name==var) return const_cast<DepTree*>(this); |
||||||
|
|
||||||
|
DepTree* d; |
||||||
|
for(auto& i:childrens) |
||||||
|
{ |
||||||
|
d=i->FindNodeByVarFromCurrent(var); |
||||||
|
if(d!=0) return d; |
||||||
|
} |
||||||
|
return 0; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
DepTree* DepTree::FindNodeByVar(const std::string& var) const |
||||||
|
{ |
||||||
|
const DepTree* curnode=this; |
||||||
|
while(curnode->parents.size()!=0) curnode=*(curnode->parents.begin()); |
||||||
|
return curnode->FindNodeByVarFromCurrent(var); |
||||||
|
} |
@ -0,0 +1,38 @@ |
|||||||
|
#ifndef DEPTREE_H |
||||||
|
#define DEPTREE_H |
||||||
|
#include <set> |
||||||
|
#include <vector> |
||||||
|
#include <string> |
||||||
|
#include "object.h" |
||||||
|
|
||||||
|
class DepTree |
||||||
|
{ |
||||||
|
enum NodeType {NOTDEF,ROOT,SAVE,PRINT,VAR}; |
||||||
|
|
||||||
|
std::set<DepTree*> parents; |
||||||
|
std::set<DepTree*> childrens; |
||||||
|
NodeType type; |
||||||
|
std::vector<ObjectList*>::size_type index; |
||||||
|
std::string name; |
||||||
|
|
||||||
|
int CreateNodeFromVar(const std::string& var, std::set<std::string>& used, std::set<DepTree*>& callstack); |
||||||
|
int CreateNodeFromSP(NodeType list, std::vector<ObjectList*>::size_type ind, std::set<std::string>& used); |
||||||
|
DepTree* FindNodeByVarFromCurrent(const std::string& var) const; |
||||||
|
DepTree* FindNodeByVar(const std::string& var) const; |
||||||
|
public: |
||||||
|
DepTree():type(DepTree::NOTDEF) {} |
||||||
|
DepTree(const DepTree&) = delete; |
||||||
|
~DepTree() |
||||||
|
{ |
||||||
|
for(auto& i:parents) i->childrens.erase(this); |
||||||
|
for(auto& i:childrens) |
||||||
|
{ |
||||||
|
i->parents.erase(this); |
||||||
|
if(i->parents.size()==0) delete i; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
int CreateGlobalTree(std::set<std::string>& used); |
||||||
|
}; |
||||||
|
|
||||||
|
#endif |
Loading…
Reference in new issue