diff --git a/include/common.h b/include/common.h index 02dea26..79a257b 100644 --- a/include/common.h +++ b/include/common.h @@ -36,15 +36,17 @@ inline std::string ToString(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 }; +// Error class +class EXPORT ObjectError: public ObjectBase +{ + std::string function, reason; + ObjectError() = delete; + ObjectError(const ObjectError&) = delete; + ObjectError(ObjectError&&) = delete; + public: + template + 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)< class EXPORT ObjectSimple: public ObjectBase diff --git a/src/object.cpp b/src/object.cpp index e6ffc1b..5060402 100644 --- a/src/object.cpp +++ b/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 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(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 "<Name()<<" at line "<Function()<<": "<Reason()<