diff --git a/include/common.h b/include/common.h index d62e9dc..b4a24cf 100644 --- a/include/common.h +++ b/include/common.h @@ -154,6 +154,8 @@ class OBTypeM }; +typedef std::shared_ptr 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 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)<Type()< ListValues; + typedef std::deque ListValues; private: std::shared_ptr 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()) {}; + ObjectList(const ObjectBase* o): vals(std::make_shared()) {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)<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 pair(i); - OBType list(i); - if(pair) p=pair->Find(gname); - else if(list) p=list->Find(gname); + OBType pair(i.get()); + OBType 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*); diff --git a/include/object.h b/include/object.h index d14998e..3464810 100644 --- a/include/object.h +++ b/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 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 diff --git a/src/deptree.cpp b/src/deptree.cpp index 8706b85..0032ee3 100644 --- a/src/deptree.cpp +++ b/src/deptree.cpp @@ -299,8 +299,8 @@ void* TreeEvaluateM(void* arg) if(DepTree::SAVE==leaf->type) { err=false; - - std::unique_ptr ol(dynamic_cast(Evaluate(leaf->exe,&err))); // No check for return value, trust in grammatical parser + auto olp=Evaluate(leaf->exe,&err); + auto ol=dynamic_cast(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 ol(dynamic_cast(Evaluate(leaf->exe,&err))); // No check for return value, trust in grammatical parser + auto olp=Evaluate(leaf->exe,&err); + auto ol=dynamic_cast(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 ol(dynamic_cast(Evaluate(leaf->exe,&err))); // No check for return value, trust in grammatical parser + auto olp=Evaluate(leaf->exe,&err); + auto ol=dynamic_cast(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 ol(dynamic_cast(Evaluate(leaf->exe,&err))); // No check for return value, trust in grammatical parser + auto olp=Evaluate(leaf->exe,&err); + auto ol=dynamic_cast(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; diff --git a/src/object.cpp b/src/object.cpp index e310262..729bcd7 100644 --- a/src/object.cpp +++ b/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(); 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 diff --git a/src/parser/grammatical.y b/src/parser/grammatical.y index 21e4c60..2674abb 100644 --- a/src/parser/grammatical.y +++ b/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));}