Compare commits

...

1 Commits

  1. 65
      include/common.h
  2. 46
      include/object.h
  3. 34
      src/deptree.cpp
  4. 14
      src/object.cpp
  5. 8
      src/parser/grammatical.y

65
include/common.h

@ -154,6 +154,8 @@ class OBTypeM<Func>
};
typedef std::shared_ptr<const ObjectBase> ObjPtr;
// Error class
class EXPORT ObjectError: public ObjectBase
{
@ -215,7 +217,6 @@ public:
// Own functions
T Value() const {return val;}
void SetValue(T s) {val=s;}
};
// Simple objects
@ -236,23 +237,22 @@ class EXPORT ObjectPair: public ObjectBase
{
private:
std::string name;
std::shared_ptr<const ObjectBase> val;
ObjPtr val;
ObjectPair(const ObjectPair* p):name(p->name),val(p->val) {}
public:
ObjectPair() {}
ObjectPair() = delete;
ObjectPair(const std::string& n, const ObjectBase* v):name(n) {val.reset(v);}
ObjectPair(std::string&& n, const ObjectBase* v):name(std::move(n)) {val.reset(v);}
ObjectPair(const std::string* n, const ObjectBase* v):name(*n) {val.reset(v);}
~ObjectPair() {}
ObjectPair(const std::string& n, const ObjPtr& v):name(n),val(v) {}
// Pure virtual overrides
const ObjectBase* Copy() const override
{
auto ret=new ObjectPair;
ret->name=name; ret->val=val;
return ret;
return new ObjectPair(this);
}
bool Print() const override
{
if(!Exist()) return false;
COUT(NORMAL)<<std::endl<<"Object type: "<<Type()<<std::endl;
COUT(NORMAL)<<"Name is: "<<Name()<<std::endl;
COUT(NORMAL)<<"Value type: "<<val->Type()<<std::endl;
@ -264,20 +264,12 @@ public:
std::string Dump() const override { return Name()+"="+val->Dump(); }
// Own functions
bool Exist() const {return nullptr!=val.get();}
const ObjectBase* Get(const std::string& gname) const
{
if(gname==name) return val->Copy();
else return new ObjectError("ObjectPair Get","pair has name "+name+" not "+gname);
}
// This function is same as Get but return pointer on constant object
const ObjectBase* Find(const std::string& gname) const
{
if(gname==name) return val.get();
else return nullptr;
}
std::string Name() const {return name;}
void SetPair(const std::string& n, const ObjectBase* v) {if(!Exist()) {name=n; val.reset(v);}}
const ObjectBase* Value() const {return val.get();}
};
@ -285,24 +277,18 @@ public:
class EXPORT ObjectList: public ObjectBase
{
public:
typedef std::deque<const ObjectBase*> ListValues;
typedef std::deque<ObjPtr> ListValues;
private:
std::shared_ptr<ListValues> vals;
ObjectList(const ObjectList* l):vals(l->vals) {}
public:
ObjectList() {vals.reset(new ListValues, [](ListValues* p){for(auto& i: *p) delete i; delete p;});}
ObjectList(const ObjectBase* o) {vals.reset(new ListValues, [](ListValues* p){for(auto& i: *p) delete i; delete p;}); PushBack(o);}
~ObjectList() {}
ObjectList(): vals(std::make_shared<ListValues>()) {};
ObjectList(const ObjectBase* o): vals(std::make_shared<ListValues>()) {vals->push_back(ObjPtr(o));}
// Pure virtual overrides
const ObjectBase* Copy() const override
{
auto ret=new ObjectList;
ret->vals=vals;
return ret;
}
const ObjectBase* Copy() const override {return new ObjectList(this);}
bool Print() const override
{
if(!Exist()) return false;
COUT(NORMAL)<<std::endl<<"Object type: "<<Type()<<std::endl;
COUT(NORMAL)<<"Number of elements: "<<Size()<<std::endl;
return true;
@ -319,31 +305,26 @@ public:
}
// Own functions
const ObjectBase* At(ListValues::size_type i) const {return (*vals)[i];}
bool Exist() const {return 0!=vals->size();}
const ObjectBase* At(ListValues::size_type i) const {return (*vals)[i].get();}
const ObjectBase* Get(const std::string& gname) const
{
const ObjectBase* p=Find(gname);
return (nullptr==p)?new ObjectError("ObjectList Get","name "+gname+" not found in list"):p->Copy();
}
// This function is same as Get but return pointer on constant object
const ObjectBase* Find(const std::string& gname) const
{
const ObjectBase* p;
for(auto& i: *vals)
for(const auto& i: *vals)
{
p=nullptr;
OBType<ObjectPair> pair(i);
OBType<ObjectList> list(i);
if(pair) p=pair->Find(gname);
else if(list) p=list->Find(gname);
OBType<ObjectPair> pair(i.get());
OBType<ObjectList> list(i.get());
if(pair) p=pair->Get(gname);
else if(list) p=list->Get(gname);
if(nullptr!=p) return p;
}
return nullptr;
}
ListValues::size_type Size() const {return vals->size();}
ObjectList* PushBack(const ObjectBase* p) {vals->push_back(p); return this;}
ObjectList* PushFront(const ObjectBase* p) {vals->push_front(p); return this;}
ObjectList* PushBack(const ObjectBase* p) {vals->push_back(ObjPtr(p)); return this;}
ObjectList* PushBack(const ObjPtr& p) {vals->push_back(p); return this;}
ObjectList* PushFront(const ObjectBase* p) {vals->push_front(ObjPtr(p)); return this;}
ObjectList* PushFront(const ObjPtr& p) {vals->push_front(p); return this;}
};
typedef const ObjectBase* (*Func)(const ObjectList*);

46
include/object.h

@ -40,35 +40,24 @@ public:
if(TYPE_VARIABLE==t || TYPE_FUNCTION==t || TYPE_MKPAIR==t) name=s;
else type=TYPE_EMPTY;
}
StackElem(ObjectBase* o, const struct grammatic_location& loc):type(TYPE_OBJECT),obj(o),location(loc) {}
~StackElem() {if(TYPE_OBJECT==type) delete obj;}
StackElem(StackElem&& s):type(s.type),name(s.name),location(s.location)
{
if(TYPE_OBJECT==type)
{
// Simple copy of pointer
obj=s.obj;
// Prevent destruction of ObjectBase in StackElem destructor
s.type=TYPE_EMPTY;
}
}
StackElem(const ObjPtr& o, const struct grammatic_location& loc):type(TYPE_OBJECT),obj(o),location(loc) {}
StackElem(ObjPtr&& o, const struct grammatic_location& loc):type(TYPE_OBJECT),obj(std::move(o)),location(loc) {}
StackElem(StackElem&& s) = default;
const ObjectBase* Object() const {return isObject()?obj:nullptr;}
// Detach object
const ObjectBase* PickObject()
const ObjectBase* Object() const {return isObject()?obj.get():nullptr;}
const ObjPtr& PickObject() const {return obj;}
bool ReplaceByObject(const ObjPtr& ob)
{
if(isObject())
{
type=TYPE_EMPTY;
return obj;
}
else return nullptr;
if(isObject()) return false;
type=TYPE_OBJECT;
obj=ob;
return true;
}
bool ReplaceByObject(const ObjectBase* ob)
bool ReplaceByObject(ObjPtr&& ob)
{
if(isObject()) {delete ob; return false;}
if(isObject()) return false;
type=TYPE_OBJECT;
obj=ob;
obj=std::move(ob);
return true;
}
std::string Name() const {return (isVar() || isFunc() || isMKPair())?name:std::string();}
@ -83,7 +72,7 @@ public:
private:
Type type;
const ObjectBase* obj;
ObjPtr obj;
std::string name;
struct grammatic_location location;
};
@ -92,7 +81,7 @@ typedef std::list<StackElem> ExecExpr;
inline StackElem SEBList(const struct grammatic_location& loc) {return StackElem(StackElem::TYPE_BEGINLIST,loc);}
inline StackElem SEEList(const struct grammatic_location& loc) {return StackElem(StackElem::TYPE_ENDLIST,loc);}
inline StackElem SEObj(ObjectBase* o, const struct grammatic_location& loc) {return StackElem(o,loc);}
inline StackElem SEObj(const ObjectBase* o, const struct grammatic_location& loc) {return StackElem(ObjPtr(o),loc);}
inline StackElem SEMKPair(const std::string& s, const struct grammatic_location& loc) {return StackElem(StackElem::TYPE_MKPAIR,loc,s);}
inline StackElem SEVar(const std::string& s, const struct grammatic_location& loc) {return StackElem(StackElem::TYPE_VARIABLE,loc,s);}
inline StackElem SEFunc(const std::string& s, const struct grammatic_location& loc) {return StackElem(StackElem::TYPE_FUNCTION,loc,s);}
@ -104,8 +93,7 @@ std::string DumpExprE(const ExecExpr& exp);
std::string DumpExpr(const ExecExpr& exp);
UsedType UsedVars(const ExecExpr& exp);
UsedType UsedFuncs(const ExecExpr& exp);
const ObjectBase* Evaluate(ExecExpr& exp, bool* err);
//inline void ReplaceVar(ExecExpr& exp, const std::string& var, ObjectBase* ob) {for(auto& se: exp) if(se.isVar() && var==se.Name()) se.ReplaceByObject(ob);}
void ReplaceVar(ExecExpr& exp, const std::string& var, const ObjectBase* ob);// {for(auto& se: exp) if(se.isVar() && var==se.Name()) se.ReplaceByObject(ob);}
ObjPtr Evaluate(ExecExpr& exp, bool* err);
void ReplaceVar(ExecExpr& exp, const std::string& var, const ObjPtr& ob);
#endif

34
src/deptree.cpp

@ -299,8 +299,8 @@ void* TreeEvaluateM(void* arg)
if(DepTree::SAVE==leaf->type)
{
err=false;
std::unique_ptr<const ObjectList> ol(dynamic_cast<const ObjectList*>(Evaluate(leaf->exe,&err))); // No check for return value, trust in grammatical parser
auto olp=Evaluate(leaf->exe,&err);
auto ol=dynamic_cast<const ObjectList*>(olp.get()); // No check for return value, trust in grammatical parser
if(err)
{
const struct grammatic_location& loc=leaf->exe.front().Location();
@ -309,7 +309,7 @@ void* TreeEvaluateM(void* arg)
p->exitcode=1;
return nullptr;
}
if(!Save(ol.get()))
if(!Save(ol))
{
p->exitcode=1;
return nullptr;
@ -325,8 +325,8 @@ void* TreeEvaluateM(void* arg)
if(DepTree::PRINT==leaf->type)
{
err=false;
std::unique_ptr<const ObjectList> ol(dynamic_cast<const ObjectList*>(Evaluate(leaf->exe,&err))); // No check for return value, trust in grammatical parser
auto olp=Evaluate(leaf->exe,&err);
auto ol=dynamic_cast<const ObjectList*>(olp.get()); // No check for return value, trust in grammatical parser
if(err)
{
const struct grammatic_location& loc=leaf->exe.front().Location();
@ -335,7 +335,7 @@ void* TreeEvaluateM(void* arg)
p->exitcode=1;
return nullptr;
}
if(!Print(ol.get()))
if(!Print(ol))
{
p->exitcode=1;
return nullptr;
@ -351,11 +351,9 @@ void* TreeEvaluateM(void* arg)
if(DepTree::VAR==leaf->type)
{
const ObjectBase *eob;
// Main working call
err=false;
eob=Evaluate(leaf->exe,&err);
ObjPtr eob(Evaluate(leaf->exe,&err));
if(err)
{
const struct grammatic_location& loc=leaf->exe.front().Location();
@ -383,7 +381,6 @@ void* TreeEvaluateM(void* arg)
}
// End critical section
pthread_mutex_unlock(&p->tree_mtx);
delete eob;
}
leaf->parents.clear();
@ -410,8 +407,8 @@ void* TreeEvaluate(void* arg)
if(DepTree::SAVE==leaf->type)
{
err=false;
std::unique_ptr<const ObjectList> ol(dynamic_cast<const ObjectList*>(Evaluate(leaf->exe,&err))); // No check for return value, trust in grammatical parser
auto olp=Evaluate(leaf->exe,&err);
auto ol=dynamic_cast<const ObjectList*>(olp.get()); // No check for return value, trust in grammatical parser
if(err)
{
const struct grammatic_location& loc=leaf->exe.front().Location();
@ -421,7 +418,7 @@ void* TreeEvaluate(void* arg)
return nullptr;
}
// eob is evaluated object
if(!Save(ol.get()))
if(!Save(ol))
{
p->exitcode=1;
return nullptr;
@ -433,8 +430,8 @@ void* TreeEvaluate(void* arg)
if(DepTree::PRINT==leaf->type)
{
err=false;
std::unique_ptr<const ObjectList> ol(dynamic_cast<const ObjectList*>(Evaluate(leaf->exe,&err))); // No check for return value, trust in grammatical parser
auto olp=Evaluate(leaf->exe,&err);
auto ol=dynamic_cast<const ObjectList*>(olp.get()); // No check for return value, trust in grammatical parser
if(err)
{
const struct grammatic_location& loc=leaf->exe.front().Location();
@ -443,7 +440,7 @@ void* TreeEvaluate(void* arg)
p->exitcode=1;
return nullptr;
}
if(!Print(ol.get()))
if(!Print(ol))
{
p->exitcode=1;
return nullptr;
@ -454,11 +451,9 @@ void* TreeEvaluate(void* arg)
if(DepTree::VAR==leaf->type)
{
const ObjectBase *eob;
// Main working call
err=false;
eob=Evaluate(leaf->exe,&err);
ObjPtr eob(Evaluate(leaf->exe,&err));
if(err)
{
const struct grammatic_location& loc=leaf->exe.front().Location();
@ -477,7 +472,6 @@ void* TreeEvaluate(void* arg)
// If node have no children, it's a new leaf node
if(0==i->childrens.size() && DepTree::ROOT!=i->type) p->leafs.push_back(i);
}
delete eob;
}
leaf->parents.clear();
delete leaf;

14
src/object.cpp

@ -114,7 +114,7 @@ UsedType UsedFuncs(const ExecExpr& exp)
return ret;
}
const ObjectBase* Evaluate(ExecExpr& exp, bool* err)
ObjPtr Evaluate(ExecExpr& exp, bool* err)
{
ExecExpr::iterator cse=exp.begin();
while(cse!=exp.end())
@ -123,7 +123,7 @@ const ObjectBase* Evaluate(ExecExpr& exp, bool* err)
{
case(StackElem::TYPE_ENDLIST): // Making list
{
ObjectList* ol=new ObjectList;
auto ol=std::make_shared<ObjectList>();
ExecExpr::iterator bl,el;
bl=el=cse++;
bl--;
@ -141,7 +141,7 @@ const ObjectBase* Evaluate(ExecExpr& exp, bool* err)
// Previous element must be OBJECT. We don't check this, we trust in grammatical parser.
ExecExpr::iterator pr=cse;
pr--;
cse->ReplaceByObject(new ObjectPair(cse->Name(),pr->PickObject()));
cse->ReplaceByObject(ObjPtr(new ObjectPair(cse->Name(),pr->PickObject())));
// Remove previous element
exp.erase(pr);
// Go to next element
@ -184,7 +184,7 @@ const ObjectBase* Evaluate(ExecExpr& exp, bool* err)
return nullptr;
}
// Replace function on returned value
cse->ReplaceByObject(res);
cse->ReplaceByObject(ObjPtr(res));
// Go to next element
cse++; continue;
}
@ -192,16 +192,16 @@ const ObjectBase* Evaluate(ExecExpr& exp, bool* err)
}
}
// After all, our list contains only one object.
const ObjectBase* ret=exp.begin()->PickObject();
ObjPtr ret=exp.begin()->PickObject();
exp.clear();
return ret;
}
void ReplaceVar(ExecExpr& exp, const std::string& var, const ObjectBase* ob)
void ReplaceVar(ExecExpr& exp, const std::string& var, const ObjPtr& ob)
{
for(auto& se: exp)
if(se.isVar() && var==se.Name())
se.ReplaceByObject(ob->Copy());
se.ReplaceByObject(ob);
}
bool ObjectBase::Save(const char* fname) const

8
src/parser/grammatical.y

@ -148,8 +148,8 @@ pair:
;
object:
STRING {COUT(DEBUG)<<" STRING\n"; I($$); $$->push_back(StackElem(new ObjectString($1),@1)); delete $1;}
| BOOL {COUT(DEBUG)<<" BOOL\n"; I($$); $$->push_back(StackElem(new ObjectBool($1),@1));}
STRING {COUT(DEBUG)<<" STRING\n"; I($$); $$->push_back(SEObj(new ObjectString($1),@1)); delete $1;}
| BOOL {COUT(DEBUG)<<" BOOL\n"; I($$); $$->push_back(SEObj(new ObjectBool($1),@1));}
| OBRACE list CBRACE {COUT(DEBUG)<<" OBRACE list CBRACE\n"; I($$); $$->push_front(SEBList(@1)); EADD($$,$2); $$->push_back(SEEList(@3));}
| expression %prec ASSIGN {COUT(DEBUG)<<" expression\n"; I($$); EADD($$,$1);}
| pair {COUT(DEBUG)<<" pair\n"; I($$); EADD($$,$1);}
@ -166,8 +166,8 @@ expression:
| IDENTIFIER OBRACE object CBRACE {COUT(DEBUG)<<" IDENTIFIER OBRACE object CBRACE\n"; I($$); $$->push_front(SEBList(@2)); EADD($$,$3); $$->push_back(SEEList(@4)); $$->push_back(SEFunc($1,@1)); delete $1;}
| IDENTIFIER OBRACE list CBRACE {COUT(DEBUG)<<" IDENTIFIER OBRACE list CBRACE\n"; I($$); $$->push_front(SEBList(@2)); EADD($$,$3); $$->push_back(SEEList(@4)); $$->push_back(SEFunc($1,@1)); delete $1;}
| longidentifier {COUT(DEBUG)<<" longidentifier\n"; I($$); EADD($$,$1);}
| REAL {COUT(DEBUG)<<" REAL\n"; I($$); $$->push_front(StackElem(new ObjectReal($1),@1));}
| INTEGER {COUT(DEBUG)<<" INTEGER\n"; I($$); $$->push_front(StackElem(new ObjectInt($1),@1));}
| REAL {COUT(DEBUG)<<" REAL\n"; I($$); $$->push_front(SEObj(new ObjectReal($1),@1));}
| INTEGER {COUT(DEBUG)<<" INTEGER\n"; I($$); $$->push_front(SEObj(new ObjectInt($1),@1));}
| expression '-' expression {COUT(DEBUG)<<" -\n"; I($$); $$->push_front(SEBList(@1)); EADD($$,$1); EADD($$,$3); $$->push_back(SEEList(@3)); $$->push_back(SEFunc("SUB",@2));}
| expression '+' expression {COUT(DEBUG)<<" +\n"; I($$); $$->push_front(SEBList(@1)); EADD($$,$1); EADD($$,$3); $$->push_back(SEEList(@3)); $$->push_back(SEFunc("ADD",@2));}
| expression '/' expression {COUT(DEBUG)<<" /\n"; I($$); $$->push_front(SEBList(@1)); EADD($$,$1); EADD($$,$3); $$->push_back(SEEList(@3)); $$->push_back(SEFunc("DIV",@2));}

Loading…
Cancel
Save