Zen
A cross-platform functional programming language

/home/renji/Data/projects/zenlang/sources/zbl/zrt.hpp

Go to the documentation of this file.
00001 
00005 #pragma once
00006 
00007 //#define TRACE_RUN
00008 //#define TRACE_JOIN
00009 
00010 #ifdef TRACE_RUN
00011 
00012 #define TRACE_FUNCTION(s) zbl::Tracer _t_(z::string(s));unused(_t_)
00013 #else
00014 
00015 #define TRACE_FUNCTION(s)
00016 #endif
00017 
00019 namespace zbl {
00021 
00024     z::stream& dlog();
00025 
00029     z::stream& mlog();
00030 
00034     z::stream& wlog();
00035 
00039     z::stream& elog();
00040 
00042 
00044     class Tracer {
00045     public:
00048         inline Tracer(const z::string& fname) : _fname(fname) {qDebug() << ">" << _fname;}
00049 
00052         inline ~Tracer() {qDebug() << "<" << _fname;}
00053 
00054     private:
00056         const z::string _fname;
00057     };
00058 
00060 
00062     class Runner {
00063     protected:
00066         inline Runner(){}
00067 
00068     public:
00071         virtual ~Runner(){}
00072 
00073     public:
00077         virtual bool enterRun() = 0;
00078 
00082         virtual bool leaveRun() = 0;
00083     };
00084 
00086 
00088     class Linker : public Runner {
00089     public:
00092         inline Linker(){}
00093 
00096         virtual ~Linker(){}
00097 
00098     private:
00102         virtual bool enterRun();
00103 
00107         virtual bool leaveRun();
00108     };
00109 
00111 
00113     class Joiner : public Runner {
00114     public:
00117         Joiner();
00118 
00122         Joiner(const Joiner& src);
00123 
00126         virtual ~Joiner();
00127 
00128 #if defined(TRACE_RUN) || defined(TRACE_JOIN)
00129     public:
00134         virtual void trace(z::stream& os, const z::string& fn) const;
00135 
00139         inline void trace(z::stream& os) const {
00140             trace(os, z::string(""));
00141         }
00142 #endif
00143     public:
00147         virtual bool enterRun();
00148 
00152         virtual bool leaveRun();
00153 
00154     private:
00156         class Impl;
00157 
00159         Impl* _impl;
00160     };
00161 
00163 
00165     class RunContext;
00166 
00168 
00170     class Closure {
00171     public:
00174         struct Action {
00176             enum T {
00177                 Noop, 
00178                 Next, 
00179                 Loop, 
00180             };
00181         };
00182 
00183     protected:
00186         inline Closure() {}
00187 
00188     public:
00192         virtual Runner& getRunner() = 0;
00193 
00194     public:
00199         virtual Action::T runClosureWithCtx(zbl::RunContext& _ctx) = 0;
00200 
00201 #ifdef TRACE_RUN
00202     public:
00206         virtual void trace(z::stream& os) const = 0;
00207 
00212         inline void trace(const z::string& level, z::stream& os) const {
00213             os << level << "C:{this:" << this << ", ";
00214             //os << "type:" << typeid(ref(this)).name() << ", ";
00215             trace(os);
00216             os << "}" << endl;
00217         }
00218 #endif
00219     };
00220 
00222 
00224     class Continuation {
00225     public:
00227         typedef z::scopedptr<zbl::Continuation> Ptr;
00228 
00230         typedef z::list<Runner*> JoinerList;
00231 
00232     protected:
00235         inline Continuation() : _idx(0), _child(0) {
00236         }
00237 
00241         inline Continuation(const Continuation& src) : _idx(src._idx), _child(0) {
00242         }
00243 
00244     public:
00247         virtual ~Continuation() {
00248         }
00249 
00250     public:
00255         inline bool goNext(const Closure::Action::T& action);
00256 
00260         inline Closure& getCurrentClosure();
00261 
00262     public:
00266         virtual void setParent(Closure* parent) = 0;
00267 
00268 #ifdef TRACE_RUN
00269     private:
00273         virtual Closure* getParent() const = 0;
00274 
00275     public:
00280         inline void trace(const z::string& level, z::stream& os) const {
00281             os << level << "S:{this=" << this << ", idx=" << _idx << ", parent=" << getParent() << "}" << endl;
00282             for(z::list<Closure*>::iterator it(_closureList); !it.end(); ++it) {
00283                 ref(*it).trace(level + "  ", os);
00284             }
00285         }
00286 #endif
00287     public:
00292         Closure::Action::T run(zbl::RunContext& _ctx);
00293 
00294     public:
00298         virtual void clone(zbl::Continuation::Ptr& continuation) const = 0;
00299 
00300     public:
00304         inline bool hasChild() {return (0 != _child);}
00305 
00309         inline void setChild(Continuation* child) {
00310             assert(_child == 0);
00311             _child = child;
00312         }
00313 
00317         inline void getChild(zbl::Continuation::Ptr& continuation) {
00318             continuation.reset(_child);
00319             _child = 0;
00320         }
00321 
00322     public:
00326         inline JoinerList& getJoinerList() {return _joinerList;}
00327 
00328     protected:
00330         int _idx;
00331 
00333         z::list<Closure*> _closureList;
00334 
00336         JoinerList _joinerList;
00337 
00338     private:
00340         Continuation* _child;
00341     };
00342 
00344 
00346     class ContinuationList : public z::queue<zbl::Continuation*> {};
00347 
00349 
00351     class Engine;
00352 
00354 
00356     class RunContext {
00357     public:
00360         inline RunContext(Engine& engine) : _engine(engine) {}
00361 
00362     private:
00366         inline RunContext(const RunContext& src) : _engine(src._engine) {}
00367 
00368     public:
00372         inline zbl::Engine& getEngine() {return _engine;}
00373 
00377         inline void append(Continuation* continuation) {_list.append(continuation);}
00378 
00382         inline bool hasContinuation() {return (_list.size() > 0);}
00383 
00387         inline void getContinuation(zbl::Continuation::Ptr& continuation) {continuation.reset(_list.deque());}
00388 
00389     private:
00391         Engine& _engine;
00392 
00394         ContinuationList _list;
00395     };
00396 
00398 
00400     class Fiber {
00401     public:
00403         typedef z::scopedptr<Fiber> Ptr;
00404 
00405     public:
00408         inline Fiber() {
00409         }
00410 
00413         inline ~Fiber() {
00414             if(_continuationList.size() > 0) {
00415                 throw z::exception(z::string::creator("Internal error: _continuationList should be empty in Fiber::dtor").value());
00416             }
00417         }
00418 
00419     public:
00424         zbl::Closure::Action::T run(zbl::RunContext& _ctx);
00425 
00430         bool next(const Closure::Action::T& action);
00431 
00435         void clone(zbl::Fiber::Ptr& fiber) const;
00436 
00437 #ifdef TRACE_RUN
00438     public:
00443         inline void trace(const z::string& level, z::stream& os) const {
00444             os << level << "F:{this=" << this << "}" << endl;
00445             for(z::stack<Continuation*>::iterator it(_continuationList); !it.end(); ++it) {
00446                 ref(*it).trace(level + "  ", os);
00447             }
00448         }
00449 #endif
00450 
00451     public:
00456         Continuation* pushContinuation(Continuation::Ptr& continuation);
00457 
00462         bool popContinuation(Continuation::Ptr& continuation);
00463 
00468         Continuation* addContinuation(Continuation::Ptr& continuation);
00469 
00470     private:
00472         z::stack<Continuation*> _continuationList;
00473     };
00474 
00476 
00478     class TestResult {
00479     public:
00482         inline TestResult() : _passed(0), _total(0) {}
00483 
00484     public:
00489         void add(const z::string& name, const int& passed);
00490 
00493         void writeSummary();
00494 
00495     private:
00497         z::dict<z::string, int> _result;
00498 
00499     private:
00501         int _passed;
00502 
00504         int _total;
00505     };
00506 
00508 
00510     class TestFactory {
00511     protected:
00514         inline TestFactory(const z::string& name) : _tr(0), _name(name), _next(0) {
00515             _next = _head;
00516             _head = this;
00517         }
00518 
00519     public:
00523         inline void setTestResult(TestResult& tr) {_tr = ptr(tr);}
00524 
00525     public:
00529         inline const z::string& getName() const {return _name;}
00530 
00531     public:
00533         virtual Continuation* get() const = 0;
00534 
00535     protected:
00537         TestResult* _tr;
00538 
00540         const z::string _name;
00541 
00542     public:
00544         static TestFactory* _head;
00545 
00547         TestFactory* _next;
00548     };
00549 
00551 
00553     class Engine {
00554     public:
00556         enum Mode {
00557             mNone,  
00558             mHelp,  
00559             mRun,   
00560             mTest,  
00561         };
00562 
00563     public:
00568         Engine(int argc, char* argv[]);
00569 
00572         ~Engine();
00573 
00574     public:
00578         const Mode& getMode() const;
00579 
00580     public:
00586         int init(int argc, char* argv[]);
00587 
00591         int exit();
00592 
00596         int pump();
00597 
00598     public:
00602         void enque(RunContext& ctx);
00603 
00607         void registerOnExit(Continuation* continuation);
00608 
00609     private:
00611         class Impl;
00612 
00614         Impl* _impl;
00615     };
00616 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines