Browse Source

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

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

38
include/common.h

@ -36,15 +36,17 @@ inline std::string ToString<std::string>(std::string s) {return s;}
// 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 int8_t* ptr) const {};
public:
protected:
bool err;
// No save by default
virtual const int8_t* Blob(size_t* size) const { *size=0; return 0; }
virtual void DeallocBlob(const int8_t* ptr) const {};
ObjectBase():err(false) {}
public:
ObjectBase() = default;
ObjectBase(const ObjectBase&) = delete;
bool Save(const char* fname) const;
bool isError() const {return err;}
// Pure virtual api
virtual ~ObjectBase(){}
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<class T>
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.
// Sequentally call all functions with given name
auto bounds=G_funcs.equal_range(cse->Name());
std::list<const ObjectError*> errl;
for(auto f=bounds.first; f!=bounds.second; ++f)
{
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
exp.erase(pr);
// Error handling
if(nullptr==res)
if(!errl.empty())
{
const struct grammatic_location& loc=cse->Location();
*err=true; // Raise error flag
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(auto& e: errl)
{
COUT(ERROR)<<e->Function()<<": "<<e->Reason()<<std::endl;
delete e;
}
return nullptr;
}
// Replace function on returned value

Loading…
Cancel
Save