|  | 
 | #ifndef Forth_DEFINED | 
 | #define Forth_DEFINED | 
 |  | 
 | #include "SkTypes.h" | 
 |  | 
 | class ForthOutput { | 
 | public: | 
 |     virtual void show(const char output[]) = 0; | 
 | }; | 
 |  | 
 | union FloatIntDual { | 
 |     int32_t fInt; | 
 |     float   fFloat; | 
 | }; | 
 |  | 
 | static inline int32_t f2i_bits(float x) { | 
 |     FloatIntDual d; | 
 |     d.fFloat = x; | 
 |     return d.fInt; | 
 | } | 
 |  | 
 | static inline float i2f_bits(int32_t x) { | 
 |     FloatIntDual d; | 
 |     d.fInt = x; | 
 |     return d.fFloat; | 
 | } | 
 |  | 
 | class ForthEngine { | 
 | public: | 
 |     ForthEngine(ForthOutput*); | 
 |     ~ForthEngine(); | 
 |  | 
 |     int         depth() const { return fStackStop - fStackCurr; } | 
 |     void        clearStack() { fStackCurr = fStackStop; } | 
 |  | 
 |     void        push(intptr_t value); | 
 |     intptr_t    top() const { return this->peek(0); } | 
 |     intptr_t    peek(size_t index) const; | 
 |     void        setTop(intptr_t value); | 
 |     intptr_t    pop(); | 
 |  | 
 |     void        fpush(float value) { this->push(f2i_bits(value)); } | 
 |     float       fpeek(size_t i) const { return i2f_bits(this->fpeek(i)); } | 
 |     float       ftop() const { return i2f_bits(this->top()); } | 
 |     void        fsetTop(float value) { this->setTop(f2i_bits(value)); } | 
 |     float       fpop() { return i2f_bits(this->pop()); } | 
 |  | 
 |     void sendOutput(const char text[]); | 
 |  | 
 | private: | 
 |     ForthOutput* fOutput; | 
 |     intptr_t*   fStackBase; | 
 |     intptr_t*   fStackCurr; | 
 |     intptr_t*   fStackStop; | 
 |  | 
 |     void signal_error(const char msg[]) const { | 
 |         SkDebugf("ForthEngine error: %s\n", msg); | 
 |     } | 
 | }; | 
 |  | 
 | struct ForthCallBlock { | 
 |     const intptr_t* in_data; | 
 |     size_t          in_count; | 
 |     intptr_t*       out_data; | 
 |     size_t          out_count; | 
 |     size_t          out_depth; | 
 | }; | 
 |  | 
 | class ForthWord { | 
 | public: | 
 |     virtual ~ForthWord() {} | 
 |     virtual void exec(ForthEngine*) = 0; | 
 |  | 
 |     // todo: return error state of the engine | 
 |     void call(ForthCallBlock*); | 
 | }; | 
 |  | 
 | class ForthEnv { | 
 | public: | 
 |     ForthEnv(); | 
 |     ~ForthEnv(); | 
 |  | 
 |  | 
 |     void addWord(const char name[], ForthWord*); | 
 |  | 
 |     void parse(const char code[]); | 
 |  | 
 |     ForthWord* findWord(const char name[]); | 
 |  | 
 |     void run(ForthOutput* = NULL); | 
 |  | 
 | private: | 
 |     class Impl; | 
 |     Impl* fImpl; | 
 | }; | 
 |  | 
 | #endif | 
 |  |