You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

145 lines
3.1 KiB

#include "deptree.h"
int DepTree::CreateNodeFromVar(const std::string& var, UsedType& used, CallStack& 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;
}
UsedType 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, G_toType::size_type ind, UsedType& 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;
CallStack 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(UsedType& 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);
}