#ifndef OBJECT_H #define OBJECT_H #include #include #include #include #include #include "common.h" // Bison location struct grammatic_location { struct incloc { int line,column; std::string filename; }; int first_line; int first_column; int last_line; int last_column; std::list incstack; std::string filename; }; class StackElem { StackElem()=delete; StackElem(const StackElem&)=delete; public: enum Type {TYPE_EMPTY,TYPE_BEGINLIST,TYPE_ENDLIST,TYPE_MKPAIR,TYPE_OBJECT,TYPE_VARIABLE,TYPE_FUNCTION}; StackElem(Type t, const struct grammatic_location& loc, const char* s=nullptr):type(t),obj(nullptr),location(loc) { if(TYPE_BEGINLIST==t || TYPE_ENDLIST==t) return; if( (TYPE_VARIABLE==t || TYPE_FUNCTION==t || TYPE_MKPAIR==t) && nullptr!=s) name=s; else type=TYPE_EMPTY; } StackElem(Type t, const struct grammatic_location& loc, const std::string& s):type(t),obj(nullptr),location(loc) { 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; } } const ObjectBase* Object() const {return isObject()?obj:nullptr;} // Detach object ObjectBase* PickObject() { if(isObject()) { type=TYPE_EMPTY; return obj; } else return nullptr; } bool ReplaceByObject(ObjectBase* ob) { if(isObject()) {delete ob; return false;} type=TYPE_OBJECT; obj=ob; return true; } std::string Name() const {return (isVar() || isFunc() || isMKPair())?name:std::string();} bool isObject() const {return (TYPE_OBJECT==type);} bool isVar() const {return (TYPE_VARIABLE==type);} bool isFunc() const {return (TYPE_FUNCTION==type);} bool isBList() const {return (TYPE_BEGINLIST==type);} bool isEList() const {return (TYPE_ENDLIST==type);} bool isMKPair() const {return (TYPE_MKPAIR==type);} const struct grammatic_location& Location() const {return location;} Type T() const {return type;} private: Type type; ObjectBase* obj; std::string name; struct grammatic_location location; }; 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 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);} 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);} std::string DumpExprE(const ExecExpr& exp); std::string DumpExpr(const ExecExpr& exp); UsedType UsedVars(const ExecExpr& exp); UsedType UsedFuncs(const ExecExpr& exp); 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);} #endif