|
|
@ -4,278 +4,7 @@ |
|
|
|
#include <errno.h> |
|
|
|
#include <errno.h> |
|
|
|
#include <string.h> |
|
|
|
#include <string.h> |
|
|
|
#include <inttypes.h> |
|
|
|
#include <inttypes.h> |
|
|
|
#include <vector> |
|
|
|
#include "common.h" |
|
|
|
#include <sstream> |
|
|
|
|
|
|
|
#include <set> |
|
|
|
|
|
|
|
#include <memory> |
|
|
|
|
|
|
|
#include <typeinfo> |
|
|
|
|
|
|
|
#include <typeindex> |
|
|
|
|
|
|
|
#include "debug.h" |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Check if pointer is ObjectBase derivative class
|
|
|
|
|
|
|
|
#define IS_OTYPE(quo,equ) (std::type_index(typeid(*quo))==std::type_index(typeid(equ))) |
|
|
|
|
|
|
|
#define IS_OTYPEI(quo,equ) (std::type_index(typeid(quo))==std::type_index(typeid(equ))) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
typedef std::set<std::string> UsedType; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Base class for all objects
|
|
|
|
|
|
|
|
class EXPORT ObjectBase |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
protected: |
|
|
|
|
|
|
|
// No save by default
|
|
|
|
|
|
|
|
virtual const int8_t* Blob(size_t* size) const { *size=0; return 0; } |
|
|
|
|
|
|
|
virtual void DeallocBlob(const void* ptr) const {}; |
|
|
|
|
|
|
|
public: |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ObjectBase() = default; |
|
|
|
|
|
|
|
ObjectBase(const ObjectBase&) = delete; |
|
|
|
|
|
|
|
virtual ~ObjectBase(){} |
|
|
|
|
|
|
|
virtual std::string Type() const=0; |
|
|
|
|
|
|
|
virtual bool Print() const=0; |
|
|
|
|
|
|
|
bool Save(const char* fname) const |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
size_t size,offset=0,wr; |
|
|
|
|
|
|
|
const int8_t* dptr; |
|
|
|
|
|
|
|
FILE* fd; |
|
|
|
|
|
|
|
int serrno; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fd=fopen(fname,"w"); |
|
|
|
|
|
|
|
serrno=errno; |
|
|
|
|
|
|
|
if(0==fd) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
COUT(ERROR)<<"Can't open file "<<fname<<" for writing: "<<strerror(serrno)<<std::endl; |
|
|
|
|
|
|
|
return false; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
dptr=Blob(&size); |
|
|
|
|
|
|
|
if(0==dptr) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
COUT(ERROR)<<"Can't get blob for writing to "<<fname<<std::endl; |
|
|
|
|
|
|
|
fclose(fd); |
|
|
|
|
|
|
|
return false; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
while(offset!=size) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
wr=fwrite(dptr+offset,1,size-offset,fd); |
|
|
|
|
|
|
|
if(0==wr) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
COUT(ERROR)<<"Failed to write in file "<<fname<<std::endl; |
|
|
|
|
|
|
|
fclose(fd); DeallocBlob(dptr); |
|
|
|
|
|
|
|
return false; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
offset+=wr; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
fclose(fd); |
|
|
|
|
|
|
|
DeallocBlob(dptr); |
|
|
|
|
|
|
|
return true; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
virtual std::string Dump() const {return "%"+Type()+"%";} |
|
|
|
|
|
|
|
virtual void UsedFuncs(UsedType& funcs) const {} |
|
|
|
|
|
|
|
virtual void UsedIdents(UsedType& ids) const {} |
|
|
|
|
|
|
|
virtual ObjectBase* Copy() const=0; |
|
|
|
|
|
|
|
virtual ObjectBase* Evaluate(bool* err) {*err=false; return 0;} |
|
|
|
|
|
|
|
virtual ObjectBase* ReplaceVar(const std::string& vname, ObjectBase* ob) {return 0;} |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Template for objects without specific constructor/destructor
|
|
|
|
|
|
|
|
template<class T> |
|
|
|
|
|
|
|
class EXPORT ObjectSimple: public ObjectBase |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
private: |
|
|
|
|
|
|
|
T val; |
|
|
|
|
|
|
|
static std::string type; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const int8_t* Blob(size_t* size) const override |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
*size=sizeof(T); |
|
|
|
|
|
|
|
return reinterpret_cast<const int8_t*>(&val); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public: |
|
|
|
|
|
|
|
ObjectSimple(T t):val(t) {} |
|
|
|
|
|
|
|
ObjectSimple(const T* t):val(*t) {} |
|
|
|
|
|
|
|
~ObjectSimple() {} |
|
|
|
|
|
|
|
bool Print() const override |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
COUT(NORMAL)<<std::endl<<"Object type: "<<Type()<<std::endl; |
|
|
|
|
|
|
|
COUT(NORMAL)<<"Value: "<<val<<std::endl; |
|
|
|
|
|
|
|
return true; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
std::string Type() const override {return type;} |
|
|
|
|
|
|
|
T Value() const {return val;} |
|
|
|
|
|
|
|
void SetValue(T s) {val=s;} |
|
|
|
|
|
|
|
std::string Dump() const override |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
std::stringstream s; |
|
|
|
|
|
|
|
if(std::type_index(typeid(T))==std::type_index(typeid(std::string))) |
|
|
|
|
|
|
|
s<<"\""<<val<<"\""; |
|
|
|
|
|
|
|
else |
|
|
|
|
|
|
|
s<<val; |
|
|
|
|
|
|
|
return s.str(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
ObjectBase* Copy() const override {return new ObjectSimple<T>(val);} |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Simple objects
|
|
|
|
|
|
|
|
typedef ObjectSimple<bool> ObjectBool; |
|
|
|
|
|
|
|
typedef ObjectSimple<int64_t> ObjectInt; |
|
|
|
|
|
|
|
typedef ObjectSimple<double> ObjectReal; |
|
|
|
|
|
|
|
typedef ObjectSimple<std::string> ObjectString; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
template<> |
|
|
|
|
|
|
|
inline const int8_t* ObjectString::Blob(size_t* size) const |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
*size=val.length(); |
|
|
|
|
|
|
|
return reinterpret_cast<const int8_t*>(val.c_str()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Class for name-value pair
|
|
|
|
|
|
|
|
class EXPORT ObjectPair: public ObjectBase |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
private: |
|
|
|
|
|
|
|
std::string name; |
|
|
|
|
|
|
|
std::shared_ptr<ObjectBase> val; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public: |
|
|
|
|
|
|
|
ObjectPair() {} |
|
|
|
|
|
|
|
ObjectPair(const std::string& n, ObjectBase* v):name(n) {val.reset(v);} |
|
|
|
|
|
|
|
ObjectPair(const std::string* n, ObjectBase* v):name(*n) {val.reset(v);} |
|
|
|
|
|
|
|
~ObjectPair() {} |
|
|
|
|
|
|
|
bool Exist() const {return 0!=val.get();} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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; |
|
|
|
|
|
|
|
return true; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
std::string Type() const override {return "pair";} |
|
|
|
|
|
|
|
std::string Name() const {return name;} |
|
|
|
|
|
|
|
const ObjectBase* Value() const {return val.get();} |
|
|
|
|
|
|
|
void SetPair(const std::string& n, ObjectBase* v) {if(!Exist()) {name=n; val.reset(v);}} |
|
|
|
|
|
|
|
std::string Dump() const override { return Name()+"="+val->Dump(); } |
|
|
|
|
|
|
|
void UsedFuncs(UsedType& funcs) const override {return val->UsedFuncs(funcs);} |
|
|
|
|
|
|
|
void UsedIdents(UsedType& ids) const override {return val->UsedIdents(ids);} |
|
|
|
|
|
|
|
ObjectBase* Copy() const override |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
auto ret=new ObjectPair; |
|
|
|
|
|
|
|
ret->name=name; |
|
|
|
|
|
|
|
ret->val=val; |
|
|
|
|
|
|
|
return ret; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
ObjectBase* Evaluate(bool* err) override |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
auto p=val->Evaluate(err); |
|
|
|
|
|
|
|
if(*err) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
COUT(ERROR)<<" in pair "<<Dump()<<std::endl; |
|
|
|
|
|
|
|
return 0; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if(0==p) return 0; |
|
|
|
|
|
|
|
val.reset(p); |
|
|
|
|
|
|
|
return 0; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
ObjectBase* ReplaceVar(const std::string& vname, ObjectBase* ob) override |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
auto p=val->ReplaceVar(vname,ob); |
|
|
|
|
|
|
|
if(0!=p) val.reset(p); |
|
|
|
|
|
|
|
return 0; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
ObjectBase* Get(const std::string& gname) const |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
if(gname==name) return val->Copy(); |
|
|
|
|
|
|
|
else return 0; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Class for objects list
|
|
|
|
|
|
|
|
class EXPORT ObjectList: public ObjectBase |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
public: |
|
|
|
|
|
|
|
typedef std::vector<ObjectBase*> ListValues; |
|
|
|
|
|
|
|
private: |
|
|
|
|
|
|
|
std::shared_ptr<ListValues> vals; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public: |
|
|
|
|
|
|
|
ObjectList() {vals.reset(new ListValues, [](ListValues* p){for(auto& i: *p) delete i; delete p;});} |
|
|
|
|
|
|
|
ObjectList(ObjectBase* o) {vals.reset(new ListValues, [](ListValues* p){for(auto& i: *p) delete i; delete p;}); PushBack(o);} |
|
|
|
|
|
|
|
~ObjectList() {} |
|
|
|
|
|
|
|
bool Exist() const {return 0!=vals->size();} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
ListValues::size_type Size() const {return vals->size();} |
|
|
|
|
|
|
|
std::string Type() const override {return "list";} |
|
|
|
|
|
|
|
ObjectList* PushBack(ObjectBase* p) {vals->push_back(p); return this;} |
|
|
|
|
|
|
|
const ObjectBase* At(ListValues::size_type i) const {return (*vals)[i];} |
|
|
|
|
|
|
|
std::string Dump() const override |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
std::string s("("); |
|
|
|
|
|
|
|
for(auto& i: *vals) s+=i->Dump()+", "; |
|
|
|
|
|
|
|
if(vals->size()!=0) s.resize(s.length()-2); |
|
|
|
|
|
|
|
return s+")"; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
void UsedFuncs(UsedType& funcs) const override {for(auto& i: *vals) i->UsedFuncs(funcs);} |
|
|
|
|
|
|
|
void UsedIdents(UsedType& ids) const override {for(auto& i: *vals) i->UsedIdents(ids);} |
|
|
|
|
|
|
|
ObjectBase* Copy() const override |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
auto ret=new ObjectList; |
|
|
|
|
|
|
|
ret->vals=vals; |
|
|
|
|
|
|
|
return ret; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
ObjectBase* Evaluate(bool* err) override |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
ObjectBase* p; |
|
|
|
|
|
|
|
for(auto& i: *vals) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
p=i->Evaluate(err); |
|
|
|
|
|
|
|
if(*err) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
COUT(ERROR)<<" in list member "<<i->Dump()<<std::endl; |
|
|
|
|
|
|
|
return 0; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if(0!=p) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
delete i; |
|
|
|
|
|
|
|
i=p; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return 0; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
ObjectBase* ReplaceVar(const std::string& vname, ObjectBase* ob) override |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
ObjectBase* p; |
|
|
|
|
|
|
|
for(auto& i: *vals) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
p=i->ReplaceVar(vname,ob); |
|
|
|
|
|
|
|
if(0!=p) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
delete i; |
|
|
|
|
|
|
|
i=p; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return 0; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
ObjectBase* Get(const std::string& gname) const |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
ObjectBase* p; |
|
|
|
|
|
|
|
for(auto& i: *vals) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
p=0; |
|
|
|
|
|
|
|
if(IS_OTYPE(i,ObjectPair)) p=dynamic_cast<const ObjectPair*>(i)->Get(gname); |
|
|
|
|
|
|
|
if(0!=p) return p; |
|
|
|
|
|
|
|
if(IS_OTYPE(i,ObjectList)) p=dynamic_cast<const ObjectList*>(i)->Get(gname); |
|
|
|
|
|
|
|
if(0!=p) return p; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return 0; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Class for storing identifiers
|
|
|
|
// Class for storing identifiers
|
|
|
|
class OId: public ObjectBase |
|
|
|
class OId: public ObjectBase |
|
|
@ -285,17 +14,17 @@ class OId: public ObjectBase |
|
|
|
public: |
|
|
|
public: |
|
|
|
OId(const std::string* t):name(*t) {} |
|
|
|
OId(const std::string* t):name(*t) {} |
|
|
|
~OId() {} |
|
|
|
~OId() {} |
|
|
|
bool Print() const override {return false;} |
|
|
|
// Pure virtual overrides
|
|
|
|
std::string Type() const override {return "IDENT";} |
|
|
|
|
|
|
|
std::string Name() const {return name;} |
|
|
|
|
|
|
|
void SetName(const std::string& s) {name=s;} |
|
|
|
|
|
|
|
std::string Dump() const override {return name;}; |
|
|
|
|
|
|
|
void UsedIdents(UsedType& ids) const override {ids.insert(name);} |
|
|
|
|
|
|
|
ObjectBase* Copy() const override |
|
|
|
ObjectBase* Copy() const override |
|
|
|
{ |
|
|
|
{ |
|
|
|
COUT(WARNING)<<"OId::Copy: this call must never be happens."<<std::endl; |
|
|
|
COUT(WARNING)<<"OId::Copy: this call must never be happens."<<std::endl; |
|
|
|
return new OId(&name); |
|
|
|
return new OId(&name); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
bool Print() const override {return false;} |
|
|
|
|
|
|
|
std::string Type() const override {return "IDENT";} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Non-default overrides
|
|
|
|
|
|
|
|
std::string Dump() const override {return name;}; |
|
|
|
ObjectBase* Evaluate(bool* err) override |
|
|
|
ObjectBase* Evaluate(bool* err) override |
|
|
|
{ |
|
|
|
{ |
|
|
|
COUT(ERROR)<<"Variable "<<name<<" still not defined."<<std::endl; |
|
|
|
COUT(ERROR)<<"Variable "<<name<<" still not defined."<<std::endl; |
|
|
@ -307,6 +36,11 @@ public: |
|
|
|
if(vname==Name()) return ob->Copy(); |
|
|
|
if(vname==Name()) return ob->Copy(); |
|
|
|
else return 0; |
|
|
|
else return 0; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
void UsedIdents(UsedType& ids) const override {ids.insert(name);} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Own functions
|
|
|
|
|
|
|
|
std::string Name() const {return name;} |
|
|
|
|
|
|
|
// void SetName(const std::string& s) {name=s;}
|
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
// Class for storing functions
|
|
|
|
// Class for storing functions
|
|
|
@ -326,23 +60,25 @@ public: |
|
|
|
else args=new ObjectList(p); |
|
|
|
else args=new ObjectList(p); |
|
|
|
} |
|
|
|
} |
|
|
|
~OFunc() {if(args!=0) delete args;} |
|
|
|
~OFunc() {if(args!=0) delete args;} |
|
|
|
bool Print() const override {return false;} |
|
|
|
// Pure virtual overrides
|
|
|
|
std::string Type() const override {return "FUNC";} |
|
|
|
|
|
|
|
std::string Name() const {return name;} |
|
|
|
|
|
|
|
void SetName(std::string s) {name=s;} |
|
|
|
|
|
|
|
std::string Dump() const override {return Name()+args->Dump();}; |
|
|
|
|
|
|
|
void UsedFuncs(UsedType& funcs) const override {funcs.insert(name); args->UsedFuncs(funcs);} |
|
|
|
|
|
|
|
void UsedIdents(UsedType& ids) const override {args->UsedIdents(ids);} |
|
|
|
|
|
|
|
ObjectBase* Copy() const override |
|
|
|
ObjectBase* Copy() const override |
|
|
|
{ |
|
|
|
{ |
|
|
|
COUT(WARNING)<<"OFunc::Copy: this call must never be happens."<<std::endl; |
|
|
|
COUT(WARNING)<<"OFunc::Copy: this call must never be happens."<<std::endl; |
|
|
|
return new OFunc(&name,args->Copy()); |
|
|
|
return new OFunc(&name,args->Copy()); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
bool Print() const override {return false;} |
|
|
|
|
|
|
|
std::string Type() const override {return "FUNC";} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Non-default overrides
|
|
|
|
|
|
|
|
std::string Dump() const override {return Name()+args->Dump();}; |
|
|
|
ObjectBase* Evaluate(bool* err) override; |
|
|
|
ObjectBase* Evaluate(bool* err) override; |
|
|
|
ObjectBase* ReplaceVar(const std::string& vname, ObjectBase* ob) override |
|
|
|
ObjectBase* ReplaceVar(const std::string& vname, ObjectBase* ob) override {return args->ReplaceVar(vname,ob);} |
|
|
|
{ |
|
|
|
void UsedFuncs(UsedType& funcs) const override {funcs.insert(name); args->UsedFuncs(funcs);} |
|
|
|
return args->ReplaceVar(vname,ob); |
|
|
|
void UsedIdents(UsedType& ids) const override {args->UsedIdents(ids);} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Own functions
|
|
|
|
|
|
|
|
std::string Name() const {return name;} |
|
|
|
|
|
|
|
// void SetName(std::string s) {name=s;}
|
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
#endif |
|
|
|
#endif |
|
|
|