Browse Source

Add support for extended error reporting by functions (functions can return ObjectError object with description of error).

ObjPtr
Michael Uleysky 8 years ago
parent
commit
79c55b1618
  1. 28
      include/common.h
  2. 12
      src/object.cpp

28
include/common.h

@ -37,14 +37,16 @@ inline std::string ToString<std::string>(std::string s) {return s;}
class EXPORT ObjectBase class EXPORT ObjectBase
{ {
protected: protected:
bool err;
// No save by default // No save by default
virtual const int8_t* Blob(size_t* size) const { *size=0; return 0; } virtual const int8_t* Blob(size_t* size) const { *size=0; return 0; }
virtual void DeallocBlob(const int8_t* ptr) const {}; virtual void DeallocBlob(const int8_t* ptr) const {};
ObjectBase():err(false) {}
public: public:
ObjectBase() = default;
ObjectBase(const ObjectBase&) = delete; ObjectBase(const ObjectBase&) = delete;
bool Save(const char* fname) const; bool Save(const char* fname) const;
bool isError() const {return err;}
// Pure virtual api // Pure virtual api
virtual ~ObjectBase(){} virtual ~ObjectBase(){}
virtual ObjectBase* Copy() const=0; virtual ObjectBase* Copy() const=0;
@ -149,6 +151,30 @@ class OBTypeM<Func>
}; };
// Error class
class EXPORT ObjectError: public ObjectBase
{
std::string function, reason;
ObjectError() = delete;
ObjectError(const ObjectError&) = delete;
ObjectError(ObjectError&&) = delete;
public:
template<class F, class R>
ObjectError(F f, R r):function(f),reason(r) {ObjectBase::err=true;}
const std::string& Function() const {return function;}
const std::string& Reason() const {return reason;}
// Pure virtual overrides
ObjectBase* Copy() const override {return new ObjectError(function,reason);}
bool Print() const override
{
COUT(NORMAL)<<std::endl<<"Object type: "<<Type()<<std::endl;
COUT(NORMAL)<<"Value: "<<Function()<<": "<<Reason()<<std::endl;
return true;
}
std::string Type() const override {return "ERROR";}
};
// Template for objects without specific constructor/destructor // Template for objects without specific constructor/destructor
template<class T> template<class T>
class EXPORT ObjectSimple: public ObjectBase class EXPORT ObjectSimple: public ObjectBase

12
src/object.cpp

@ -158,21 +158,29 @@ ObjectBase* Evaluate(ExecExpr& exp, bool* err)
// Functions check already done, we know that our function exists. // Functions check already done, we know that our function exists.
// Sequentally call all functions with given name // Sequentally call all functions with given name
auto bounds=G_funcs.equal_range(cse->Name()); auto bounds=G_funcs.equal_range(cse->Name());
std::list<const ObjectError*> errl;
for(auto f=bounds.first; f!=bounds.second; ++f) for(auto f=bounds.first; f!=bounds.second; ++f)
{ {
res=(*(f->second))(arg); res=(*(f->second))(arg);
if(res!=nullptr) break; if( !(res==nullptr || res->isError()) ) break;
if(res==nullptr) errl.push_back(new ObjectError("Some function", "unknown reason"));
else errl.push_back(dynamic_cast<const ObjectError*>(res));
} }
// Remove previous element // Remove previous element
exp.erase(pr); exp.erase(pr);
// Error handling // Error handling
if(nullptr==res) if(!errl.empty())
{ {
const struct grammatic_location& loc=cse->Location(); const struct grammatic_location& loc=cse->Location();
*err=true; // Raise error flag *err=true; // Raise error flag
COUT(ERROR)<<"Can't evaluate function "<<cse->Name()<<" at line "<<loc.first_line<<", position "<<loc.first_column<<std::endl; COUT(ERROR)<<"Can't evaluate function "<<cse->Name()<<" at line "<<loc.first_line<<", position "<<loc.first_column<<std::endl;
for(const auto& inc: loc.incstack) COUT(ERROR)<<" included from "<<inc.filename<<" at line "<<inc.line<<", position "<<inc.column<<std::endl; for(const auto& inc: loc.incstack) COUT(ERROR)<<" included from "<<inc.filename<<" at line "<<inc.line<<", position "<<inc.column<<std::endl;
for(auto& e: errl)
{
COUT(ERROR)<<e->Function()<<": "<<e->Reason()<<std::endl;
delete e;
}
return nullptr; return nullptr;
} }
// Replace function on returned value // Replace function on returned value

Loading…
Cancel
Save